一开始这个题想的是用快排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;
} 
京公网安备 11010502036488号