SYCOJ906瑞士轮

题目—瑞士轮 (shiyancang.cn)

模拟题

#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)内完成操作,每次的名次在比完直接可以知道,那么直接按照归并双指针合并即可。

上一篇:做题记录2021.7.13


下一篇:我的TCP保活机制(TCP_KEEPALIVE)学习心得--从入门到入土