SYCOJ906瑞士轮
模拟题
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+520;
int n,r,q,res1=1,res2=1;
struct grade
{
int total,num,abi;
}a[N*4],win[N*4],lose[N*4];
bool cmp(grade x,grade y)
{
return x.total>y.total||x.total==y.total&&x.num<y.num;
}
void merge_sort(int res1,int res2)
{
int l=1,w=1,cnt=1;
while(l<res1&&w<res2)
{
if(cmp(win[l],lose[w])) a[cnt++]=win[l++];
else a[cnt++]=lose[w++];
}
while(l<res1) a[cnt++]=win[l++];
while(w<res2) a[cnt++]=lose[w++];
}
int main()
{
scanf("%d%d%d",&n,&r,&q);
for(int i=1;i<=n*2;i++) scanf("%d",&a[i].total);
for(int i=1;i<=n*2;i++) scanf("%d",&a[i].abi),a[i].num=i;
sort(a+1,a+1+n*2,cmp);
// for(int i=1;i<=n*2;i++) cout<<a[i].total<<" ";
// puts("");
while(r--)
{
res1=1,res2=1;
for(int i=1;i<=n;i++)
{
if(a[i*2-1].abi>a[i*2].abi) a[i*2-1].total++,win[res1++]=a[i*2-1],lose[res2++]=a[i*2];
else a[i*2].total++,win[res1++]=a[i*2],lose[res2++]=a[i*2-1];
}
// sort(a+1,a+1+n*2,cmp); 卡sort
// for(int i=1;i<=n*2;i++) cout<<a[i].total<<' ';
// puts("");
// for(int i=1;i<=n*2;i++) cout<<a[i].num<<' ';
// puts("");
merge_sort(res1,res2);
}
cout<<a[q].num<<'\n';
return 0;
}
如果是每次用sort会超时。
这题是一道归并题,记录每一次的win and lose ,因为本身按照排名来算的,那么其本身就是有序的,所以完全可以在o(n)内完成操作,每次的名次在比完直接可以知道,那么直接按照归并双指针合并即可。

浙公网安备 33010602011771号