[NOIP2011]瑞士轮
Posted Mrsrz
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[NOIP2011]瑞士轮相关的知识,希望对你有一定的参考价值。
题目大意:要你模拟瑞士轮赛制,求出R轮后第Q名选手的编号。
解题思路:首先对所有选手按分数从大到小进行排序,然后模拟比赛。
因为原本是排好序的,赢的加1分,输的扣1分,所以赢的人和输的人也是分别有序的。
所以我们可以把每轮赢的人扔进一个数组,输的人扔进另一个数组,然后归并就行了。
C++可以用algorithm里的sort()和merge()实现排序和归并。
时间复杂度O(2nR)。
注意n最大100000,所以最多有200000人,开数组要开200000。
C++ Code:
#include<cstdio> #include<algorithm> using namespace std; struct player{ int score,zdl,num; bool operator <(const player& rhs)const{ if(score!=rhs.score) return score>rhs.score; return num<rhs.num; } }a[200005],lft[100005],rght[100005]; int n,r,q; int main(){ scanf("%d%d%d",&n,&r,&q); for(int i=1;i<=2*n;i++)scanf("%d",&a[i].score); for(int i=1;i<=2*n;i++)scanf("%d",&a[i].zdl),a[i].num=i; sort(a+1,a+2*n+1); while(r--){ for(int i=2;i<=2*n;i+=2){ if(a[i-1].zdl>a[i].zdl){ a[i-1].score++; lft[i/2]=a[i-1]; rght[i/2]=a[i]; }else{ a[i].score++; lft[i/2]=a[i]; rght[i/2]=a[i-1]; } } merge(lft+1,lft+n+1,rght+1,rght+n+1,a+1); } printf("%d\n",a[q].num); return 0; }
以上是关于[NOIP2011]瑞士轮的主要内容,如果未能解决你的问题,请参考以下文章