洛谷P1309 瑞士轮

Posted 小时のblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P1309 瑞士轮相关的知识,希望对你有一定的参考价值。

传送门

题目大意:

2*n个人,有初始的比赛分数和实力值。

每次比赛前总分从大到小排序,总分相同编号小的排在前面。

每次比赛是1和2比,3和4比,5和6比。

实力值大的获胜得1分。

每次比赛前排序确定比赛顺序。

题解:

模拟60

哎呀忘记最后一次排序

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200007
using namespace std;

int n,r,q,t;

struct P{
    int id,sc,h;
}a[N];

bool cmp(P a,P b){
    if(a.sc==b.sc)return a.id<b.id;
    return a.sc>b.sc;
}

int main(){
    scanf("%d%d%d",&n,&r,&q);t=n;n*=2;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].sc);
        a[i].id=i;
    }
    for(int i=1;i<=n;i++)scanf("%d",&a[i].h);
    for(int i=1;i<=r;i++){
        sort(a+1,a+n+1,cmp);
        for(int i=1;i<=t;i++){
            if(a[2*i].h>a[2*i-1].h)a[2*i].sc++;
            else a[2*i-1].sc++;
        }
    }
    sort(a+1,a+n+1,cmp);
    printf("%d\n",a[q].id);
    return 0;
} 
60

正解:模拟+归并排序

60分做法时间复杂度是O()

sort的时间复杂度nlogn的

可以发现,在进行一轮比赛之后

胜的队伍+1,

败的队伍不变

所以胜的队伍的大小关系不变,败的队伍大小关系不变。

那么把每一轮胜的队伍和败的队伍分比放在一个数组里

像归并排序一样并起来。由于两个数组已经是有序的了,

所以排序的时间复杂度是O(n)的。

优化前O(r*nlogn+r*n),优化后O(2rn)

技术分享
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200007
using namespace std;

int n,r,q,t,win,lose;

struct P{
    int id,sc,h;
}a[N],w[N],l[N];

bool cmp(P a,P b){
    if(a.sc==b.sc)return a.id<b.id;
    return a.sc>b.sc;
}

bool Cp(int c1,int c2,int id1,int id2){
    if(c1>c2)return true;
    if(c1==c2&&id1<id2)return true;
    return false;
}

void merge(int ll,int rr){
    int l1=ll,l2=ll,k=ll;
    while(l1<=rr&&l2<=rr){
        if(Cp(w[l1].sc,l[l2].sc,w[l1].id,l[l2].id))a[k++]=w[l1++];
        else a[k++]=l[l2++];
    }
    while(l1<=rr)a[k++]=w[l1++];
    while(l2<=rr)a[k++]=l[l2++];
}

int main(){
    scanf("%d%d%d",&n,&r,&q);t=n;n*=2;
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i].sc);
        a[i].id=i;
    }
    for(int i=1;i<=n;i++)scanf("%d",&a[i].h);
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=r;i++){
        win=0;lose=0;
        for(int j=1;j<=t;j++){
            if(a[j*2].h>a[j*2-1].h)w[++win]=a[j*2],w[win].sc++,l[++lose]=a[j*2-1];
            else w[++win]=a[j*2-1],w[win].sc++,l[++lose]=a[j*2];
        }
        merge(1,t);
    }
    printf("%d\n",a[q].id);
    return 0;
} 
AC

 

以上是关于洛谷P1309 瑞士轮的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1309 瑞士轮

NOIP2011 普及组 T3 洛谷P1309 瑞士轮

P1309 瑞士轮 (吸氧了)

P1309 瑞士轮

P1309 瑞士轮

P1309 瑞士轮 未完成 60