一开始这个题想的是用快排sort暴力掉
但是我们可以注意到快排一次nlogn,ke8
一共50次,时间复杂度约1e10,爆定了
如果待排序数中部分数的相对序列是已知的,那么就可以用归并思想优化,
如果是序列一部分的数字满足上述“各部分数的相对序列已知”,可以对已知部分归并,对未知部分排序,再把已知和未知部分归并
本题,在第一场结束后,所有的数的所在集合相对序列都是已知,赢者集合的所有元素相对次序已知,输者集合的所有元素相对次序已知
只需归并赢者和输者即可排完一次,50次,时间复杂度1e6,;第一次快排的复杂度nlogn ,ke6;综合复杂度ke6
第一场开始sort排序 while (场数){ for (两两比较,循环一半){ if (前者实力大)ply前者的分++,赢者[]=ply前者,输者[]=ply后者 else 后者实力大 ply后者的分++,赢者[]=ply后者,输者[]=ply前者 } while (赢者遍历未完&&输者遍历未完){ if (针对赢者>针对输者) ply[指针++]=赢者[指针++] else ply[指针++]=输者[指针++] } while (赢者遍历未完)ply[指针++]=赢者[指针++] while (输者遍历未完)ply[指针++]=输者[指针++] }代码
#include <bits/stdc++.h> using namespace std; struct P{ int s,w,no; }; P ply[200005]; int n,r,q; P win[100005], lost[100005]; bool cmp(P a,P b){ if(a.s!=b.s) return a.s>b.s; return a.no<b.no; } int main(int argc, char** argv) { cin>>n>>r>>q; for(int i=1;i<=n<<1;i++) cin>>ply[i].s; for(int i=1;i<=n<<1;i++){ cin>>ply[i].w; ply[i].no=i; } sort(ply+1,ply+1+(n<<1),cmp); while(r--){ for(int i=1;i<=n;i++){ if(ply[i<<1].w>ply[(i<<1)-1].w){ ply[i<<1].s++, win[i]=ply[i<<1], lost[i]=ply[(i<<1)-1]; }else{ ply[(i<<1)-1].s++, win[i]=ply[(i<<1)-1], lost[i]=ply[i<<1]; } } int pt=1, i=1, j=1; while(i<=n&&j<=n){ if(win[i].s>lost[j].s||(win[i].s==lost[j].s&&win[i].no<lost[j].no)) ply[pt++]=win[i++]; else ply[pt++]=lost[j++]; } while(i<=n){ ply[pt++]=win[i++]; } while(j<=n){ ply[pt++]=lost[j++]; } } cout<<ply[q].no<<endl; return 0; }