其他分享
首页 > 其他分享> > 洛谷 P1309 瑞士轮

洛谷 P1309 瑞士轮

作者:互联网

洛谷 P1309 瑞士轮

传送门

这真的是一道好题,怪我早早没有去做!

这个题题意其实就是每次相邻分数的两个人根据实力值进行比较,然后比出输赢,进行分治,然后不断排序而已

第一眼的思路就是用\(sort\)去做,但是,很遗憾,超时了......仔细算一算,复杂度已经达到了上天的\(O(R*(N+N*\log N))\),所以肯定过不去,然而我的\(stable\_sort\)只\(T\)了两个点,加个\(O_2\)优化就能过去了,太诡异了

先给一下TLE的代码

/*众所周知,sort一定会超时,所以我要用sort
然而我的stable_sort只T了两个点,加个O_2就能过去了,太诡异了 */
#include<bits/stdc++.h>
#define N 200011
using namespace std;

struct node{
    int num;
    int score;
    int worth;
}a[N];

int n,r,q;

inline int read(){
    int x=0,f=1;
    char c=getchar();
    for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
    for(;isdigit(c);c=getchar())x=x*10+c-48;
    return x*f;
}

bool cmp(node x,node y){
    return x.score==y.score ? x.num<y.num : x.score>y.score;
}

int main(){
    n=read(),r=read(),q=read();
    for(int i=1;i<=2*n;i++){
        a[i].score=read();
        a[i].num=i;
    }
    for(int i=1;i<=2*n;i++){
        a[i].worth=read();
    }
    stable_sort(a+1,a+1+2*n,cmp);
    for(int i=1;i<=r;i++){
        for(int j=1;j<=n;j++){
            if(a[j*2-1].worth>a[j*2].worth)a[j*2-1].score++;
            else a[j*2].score++;
        }
        stable_sort(a+1,a+1+2*n,cmp);
    }
    cout<<a[q].num<<'\n';
}

然后我们就应该去想新的思路,这时,归并出现了,既然胜者组和败者组的相对顺序是确定的,又刚好是两个等待去排序的序列,我们就可以联想到归并排序。

我们将stu数组分成两个数组,然后就只需要将这两个序列进行归并(合并),这样就达到归并效果,复杂度\(O(N)\),而\(sort\)排序的复杂度则为\(O(N\log N)\)

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100011
using namespace std;

struct node {
    int num;
    int score;
} stu[N*2],a[N],b[N];

int n,r,q;
int w[2*N];

inline int read() {
    int x=0,f=1;
    char c=getchar();
    for(; !isdigit(c); c=getchar())if(c=='-')f=-1;
    for(; isdigit(c); c=getchar())x=x*10+c-48;
    return x*f;
}

bool cmp(node x,node y) {
    return x.score==y.score ? x.num<y.num : x.score>y.score;
}

void mergesort() { //归并排序
    int i=1,j=1,count=1;
    while(i<=n && j<=n) {
        if(a[i].score>b[j].score || (a[i].score==b[j].score&&a[i].num<b[j].num)) {
            stu[count].score=a[i].score;
            stu[count].num=a[i].num;
            count++;
            i++;
        } else {
            stu[count].score=b[j].score;
            stu[count].num=b[j].num;
            count++;
            j++;
        }
    }
    while(i<=n) {
        stu[count].score=a[i].score;
        stu[count].num=a[i].num;
        count++;
        i++;
    }
    while(j<=n) {
        stu[count].score=b[j].score;
        stu[count].num=b[j].num;
        count++;
        j++;
    }
}

int main(){
    n=read(),r=read(),q=read();
    for(int i=1;i<=2*n;i++){
        stu[i].score=read();
        stu[i].num=i;
    }
    for(int i=1;i<=2*n;i++){
        w[i]=read();
    }
    stable_sort(stu+1,stu+1+2*n,cmp);
    
    for(int j=1;j<=r;j++){
        int index=1;
        for(int i=1;i<=2*n-1;i+=2){//奇数,+2以便两两比较
            if(w[stu[i].num]>w[stu[i+1].num]){
                a[index].score=stu[i].score+1;
                a[index].num=stu[i].num;
                b[index].score=stu[i+1].score;
                b[index].num=stu[i+1].num;
                index++;
            }
            else{
                a[index].score=stu[i+1].score+1;
                a[index].num=stu[i+1].num;
                b[index].score=stu[i].score;
                b[index].num=stu[i].num;
                index++;
            }
        }
        mergesort();
    }
    cout<<stu[q].num<<'\n';
    return 0;
}

标签:sort,index,洛谷,score,int,num,stu,瑞士,P1309
来源: https://www.cnblogs.com/loceaner/p/10914023.html