洛谷 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;
}
标签:sort,index,洛谷,score,int,num,stu,瑞士,P1309 来源: https://www.cnblogs.com/loceaner/p/10914023.html