NOIP2011普及组 瑞士轮(重庆一中高2018级信息学竞赛测验4) 解题报告

NOIP2011普及组 瑞士轮(重庆一中高2018级信息学竞赛测验4) 解题报告_第1张图片


做题思路(错解):拿到这道题时,想法比较简单,直接枚举,每进行一轮比赛,将选手的得分更新,并用sort按选手的得分由大到小(得分相同,按编号由小到大)排序,最后直接输出答案。因为感觉要超时,所以用了手工输入,结果最后还是对于大的数据超时了。这种算法的时间复杂度为O(R*2*N*log2N),很明显当所有数据取最大值时,会超时。


解题思路(正解):本题的正解是运用分治算法的归并排序,在输入后先用sort排序一次,然后,每进行一轮比赛,进行一次归并排序,归并排序时,将赢的选手得分加1,并放入win数组(结构体),将输的选手放入lose数组(结构体),然后就直接将win和lose数组归并进原数组中,最后输出答案即可。这种算法的时间复杂度为O(R*2*N),不会超时。需要注意的是,在归并排序时,要注意选手得分相同时,将编号小的排在前面。


#include
#include
#include
#include
#include
using namespace std;
const int maxn=200005;
int N,R,Q;
struct data
{
	int s,w,id;
};
data a[maxn],win[maxn],lose[maxn];
bool cmp(data aa,data bb)
{
	if(aa.s!=bb.s)  return aa.s>bb.s;
	else  return aa.id'9')  ch=getchar();
	int x=0;
	while(ch>='0' && ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	a[i].s=x;
}
void _read2(int i)
{
	char ch=getchar();
	while(ch<'0' || ch>'9')  ch=getchar();
	int x=0;
	while(ch>='0' && ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	a[i].w=x;
}
void merge_sort()  
{
	int i1=1,i2=1;
	for(int i=1;i<2*N;i=i+2)  //计算该轮比赛后选手的得分,并转存至win和lose数组(结构体)中
	{
		if(a[i].w>a[i+1].w)
		{
			a[i].s++;
			win[i1++]=a[i];
			lose[i2++]=a[i+1];
		}
		if(a[i].w


你可能感兴趣的:(竞赛测验)