题意:
给出2n个选手的id,能力值和初始分数
然后按分数从大到小,id从小到大排序
相邻的选手打
能力值大的分数+1
进行r轮
问你比赛过后,排名第q的选手id是多少
思路:
开始先sort一遍,每一轮比赛都归并处理
赢得人分一组,输的人分一组,保证两组有序
然后合并到原数组
持续r轮后输出结果就好了
/* *********************************************** Author :devil Created Time :2016/6/10 14:24:16 ************************************************ */ #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #include <string> #include <cmath> #include <stdlib.h> using namespace std; const int N=1e5+10; int n; struct wq { int id,score,cap; void push(int a,int b,int c) { id=a; score=b; cap=c; } }eg[N<<1],eg1[N],eg2[N]; bool cmp(wq a,wq b) { if(a.score!=b.score) return a.score>b.score; return a.id<b.id; } void fun() { int l1=1,l2=1; for(int i=1;i<=n;i+=2) { if(eg[i].cap>eg[i+1].cap||eg[i].cap==eg[i+1].cap&&eg[i].id<eg[i+1].id) { eg1[l1++].push(eg[i].id,eg[i].score+1,eg[i].cap); eg2[l2++]=eg[i+1]; } else { eg1[l1++].push(eg[i+1].id,eg[i+1].score+1,eg[i+1].cap); eg2[l2++]=eg[i]; } } int a=1,b=1,c=1; while(a<l1&&b<l2) { if(eg1[a].score>eg2[b].score||eg1[a].score==eg2[b].score&&eg1[a].id<eg2[b].id) eg[c++]=eg1[a++]; else eg[c++]=eg2[b++]; } while(a<l1) eg[c++]=eg1[a++]; while(b<l2) eg[c++]=eg2[b++]; } int main() { //freopen("in.txt","r",stdin); int t,r,q; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&r,&q); n<<=1; for(int i=1;i<=n;i++) { scanf("%d",&eg[i].score); eg[i].id=i; } for(int i=1;i<=n;i++) scanf("%d",&eg[i].cap); sort(eg+1,eg+n+1,cmp); while(r--) fun(); printf("%d\n",eg[q].id); } return 0; }
时间: 2024-10-27 05:20:08