[2011年NOIP普及组] 瑞士轮

[2011年NOIP普及组] 瑞士轮

  • 分析:根据题意,定义结构体,将选手的序号,初始分数,实力值联系起来,在最开始先给数据排个序,跟据题意手打排序。在此我们要注意一个问题,我们已经按照分数排成有序的,那么前面的人分数一定比后面的人高,赢的人都+1,所以每次先赢的人总会在后赢的人前面,输的相同,因此我们可以将赢和输分成两个队伍。然后将每次的两个队伍实力值进行比较,赢的放入一个数组且分数+1,输的放入一个数组,最后用merge函数将这两个数组进行合并拼接排序,输出第q名的序号。
  • #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    struct node
    {
    int num;//序号
    int ma;//初始分数
    int st;//实力值
    };
    node a[1000001],w[1000001],l[1000001];
    bool cmp(node x,node y)
    {
    if(x.ma>y.ma) return true;
    else if(x.ma<y.ma) return false;
    else
    {
    if(x.num<y.num) return true;
    else return false;
    }
    }
    int main()
    {
    int n,r,q;//n名选手 r轮比赛 排名第q
    cin>>n>>r>>q;
    for(int i=1;i<=n*2;i++)
    {
    cin>>a[i].ma;
    a[i].num=i;
    }
    for(int i=1;i<=n*2;i++)//有2*n名学生
    cin>>a[i].st;
    sort(a+1,a+1+n*2,cmp);
    for(int i=1;i<=r;i++)//在r轮比赛中
    {
    int win=0,lose=0;
    for(int j=1;j<=2*n;j+=2)//因为是前后两名之间的比较,所以这里可以直接j+=2
    {
    if(a[j].st>a[j+1].st)//a[j]赢
    {
    w[++win]=a[j];//赢的数组和输的数组都加
    w[win].ma++;//赢得分数也加
    l[++lose]=a[j+1];
    }
    else //同理
    {
    w[++win]=a[j+1];
    w[win].ma++;
    l[++lose]=a[j];
    }
    }
    merge(w+1,w+1+win,l+1,l+1+lose,a+1,cmp);//合并拼接
    }
    cout<<a[q].num<<endl;
    return 0;
    }

posted @ 2022-08-13 15:53  4lovls  阅读(122)  评论(0)    收藏  举报