0720-归并排序-noip 2011 瑞士轮
程序员文章站
2022-06-04 17:20:50
...
题解
这真的是一道很简单的模拟题啊,随便模拟一下就可以了,按照题目意思一步步敲出代码,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;
}