Forever Young

洛谷 P1309 瑞士轮

洛谷 P1309 瑞士轮

思路&&代码

这真的是一道好题,怪我早早没有去做!

这个题题意其实就是每次相邻分数的两个人根据实力值进行比较,然后比出输赢,进行分治,然后不断排序而已

第一眼的思路就是用\(sort\)去做,但是,很遗憾,超时了......仔细算一算,复杂度已经达到了上天的\(O(R*(N+N*\log N))\),所以肯定过不去,然而我的\(stable\_sort\)\(T\)了两个点,加个\(O_2\)优化就能过去了,太诡异了

先给一下TLE的代码

/*众所周知,sort一定会超时,所以我要用sort
然而我的stable_sort只T了两个点,加个O_2就能过去了,太诡异了 */
#include<bits/stdc++.h>
#define N 200011
using namespace std;

struct node{
	int num;
	int score;
	int worth;
}a[N];

int n,r,q;

inline int read(){
	int x=0,f=1;
	char c=getchar();
	for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
	for(;isdigit(c);c=getchar())x=x*10+c-48;
	return x*f;
}

bool cmp(node x,node y){
	return x.score==y.score ? x.num<y.num : x.score>y.score;
}

int main(){
	n=read(),r=read(),q=read();
	for(int i=1;i<=2*n;i++){
		a[i].score=read();
		a[i].num=i;
	}
	for(int i=1;i<=2*n;i++){
		a[i].worth=read();
	}
	stable_sort(a+1,a+1+2*n,cmp);
	for(int i=1;i<=r;i++){
		for(int j=1;j<=n;j++){
			if(a[j*2-1].worth>a[j*2].worth)a[j*2-1].score++;
			else a[j*2].score++;
		}
		stable_sort(a+1,a+1+2*n,cmp);
	}
	cout<<a[q].num<<'\n';
}

然后我们就应该去想新的思路,这时,归并出现了,既然胜者组和败者组的相对顺序是确定的,又刚好是两个等待去排序的序列,我们就可以联想到归并排序。

我们将stu数组分成两个数组,然后就只需要将这两个序列进行归并(合并),这样就达到归并效果,复杂度\(O(N)\),而\(sort\)排序的复杂度则为\(O(N\log N)\)

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#define N 100011
using namespace std;

struct node {
	int num;
	int score;
} stu[N*2],a[N],b[N];

int n,r,q;
int w[2*N];

inline int read() {
	int x=0,f=1;
	char c=getchar();
	for(; !isdigit(c); c=getchar())if(c=='-')f=-1;
	for(; isdigit(c); c=getchar())x=x*10+c-48;
	return x*f;
}

bool cmp(node x,node y) {
	return x.score==y.score ? x.num<y.num : x.score>y.score;
}

void mergesort() { //归并排序
	int i=1,j=1,count=1;
	while(i<=n && j<=n) {
		if(a[i].score>b[j].score || (a[i].score==b[j].score&&a[i].num<b[j].num)) {
			stu[count].score=a[i].score;
			stu[count].num=a[i].num;
			count++;
			i++;
		} else {
			stu[count].score=b[j].score;
			stu[count].num=b[j].num;
			count++;
			j++;
		}
	}
	while(i<=n) {
		stu[count].score=a[i].score;
		stu[count].num=a[i].num;
		count++;
		i++;
	}
	while(j<=n) {
		stu[count].score=b[j].score;
		stu[count].num=b[j].num;
		count++;
		j++;
	}
}

int main(){
	n=read(),r=read(),q=read();
	for(int i=1;i<=2*n;i++){
		stu[i].score=read();
		stu[i].num=i;
	}
	for(int i=1;i<=2*n;i++){
		w[i]=read();
	}
	stable_sort(stu+1,stu+1+2*n,cmp);
	
	for(int j=1;j<=r;j++){
		int index=1;
		for(int i=1;i<=2*n-1;i+=2){//奇数,+2以便两两比较
			if(w[stu[i].num]>w[stu[i+1].num]){
				a[index].score=stu[i].score+1;
				a[index].num=stu[i].num;
				b[index].score=stu[i+1].score;
				b[index].num=stu[i+1].num;
				index++;
			}
			else{
				a[index].score=stu[i+1].score+1;
				a[index].num=stu[i+1].num;
				b[index].score=stu[i].score;
				b[index].num=stu[i].num;
				index++;
			}
		}
		mergesort();
	}
	cout<<stu[q].num<<'\n';
	return 0;
}
posted @ 2019-05-23 19:39  Loceaner  阅读(278)  评论(5编辑  收藏  举报