欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

0720-归并排序-noip 2011 瑞士轮

程序员文章站 2022-06-04 17:20:50
...

0720-归并排序-noip 2011 瑞士轮

0720-归并排序-noip 2011 瑞士轮


题解

这真的是一道很简单的模拟题啊,随便模拟一下就可以了,按照题目意思一步步敲出代码,60分就到手了

那怎么得到100分呢?

首先我们要知道只得60分是因为 T 了4组,那么是哪里重复计算(或其他什么毛病)导致时间T掉呢。

很显然是 sort 排序拖了后腿,因为其时间复杂度为n log(n)。那我们就需要另辟蹊径,找其他的排序方法,而归并排序就很符合这道题,其复杂度为O (n+m)的,又由于归并排序是对于两个有序数列干的事,所以我们要稍微处理一下,用空间去换时间

在每次操作时,赢的人和输的人分开装,然后归并就可以了


代码

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 200009
using namespace std;
long long n,r,q;
int tl,tw;
inline long long read(){
	char ch;int f=1;
	while((ch=getchar())<'0'||ch>'9')
		if(ch=='-') f=-1;
	long long res=0;
	while(ch>='0'&&ch<='9'){
		res=res*10+ch-'0';
		ch=getchar();
	}
	return f*res;
}
struct node{
	long long s,w;
	int id;
}a[N],w[N],l[N];
bool cmp(const node &a,const node &b){
	if(a.s>b.s) return 1;
	if(a.s<b.s) return 0;
	if(a.id<b.id) return 1;
	return 0;
}
void merge_h(){
	int i=1,j=1,tot=0;
	while(i<=tw&&j<=tl){
		if(cmp(w[i],l[j])) a[++tot]=w[i++];
		else a[++tot]=l[j++];
	}
	if(i<=tw){
		for(int k=i;k<=tw;++k)
			a[++tot]=w[k];
	}
	else
		for(int k=j;k<=tl;++k)
			a[++tot]=l[k];
}
int main()
{
	n=read();r=read();q=read();
	int i,j,k;
	n=2*n;
	for(i=1;i<=n;++i){
		a[i].s=read();
		a[i].id=i;
	}
	for(i=1;i<=n;++i)
		a[i].w=read();
	sort(a+1,a+n+1,cmp);
	for(int tt=1;tt<=r;++tt){
		tw=0;tl=0;
		for(i=1;i<=n;i+=2){
			if(a[i].w>a[i+1].w) a[i].s++,w[++tw]=a[i],l[++tl]=a[i+1];
			else a[i+1].s++,w[++tw]=a[i+1],l[++tl]=a[i];
		}
		merge_h();//归并
	}
	printf("%d",a[q].id);
    return 0;
}

 

相关标签: 归并排序