瑞士轮

来源:互联网 发布:应用公园软件下载 编辑:程序博客网 时间:2024/04/27 16:47
蒻苟经过一个小时的鏖战终于拿下这道题
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;int n,r,q;struct nod{int sco;int num;int ab;}a[1000005];struct fuck{int sco;int num;int ab;}win[1000005];struct node{int sco;int num;int ab;}lose[1000005];bool pk(int a,int b){if (a>b){return true;}return false;}bool cmp(nod x,nod y){if (x.sco==y.sco){return x.num < y.num;}return x.sco > y.sco;}int main(){memset(win,-1,sizeof(win));memset(lose,-1,sizeof(lose));scanf("%d%d%d",&n,&r,&q);n*=2;for (int i=1;i<=n;i++){scanf("%d",&a[i].sco);}for (int i=1;i<=n;i++){scanf("%d",&a[i].ab);}for (int i=1;i<=n;i++){a[i].num=i;}sort(a+1,a+n+1,cmp);for (int i=1;i<=r;i++){int k=-1;while (k+2<n){k+=2;if (pk(a[k].ab,a[k+1].ab)){a[k].sco++;win[k/2+1].num=a[k].num;win[k/2+1].sco=a[k].sco;win[k/2+1].ab=a[k].ab;lose[k/2+1].num=a[k+1].num;lose[k/2+1].sco=a[k+1].sco;lose[k/2+1].ab=a[k+1].ab;continue;}a[k+1].sco++;win[k/2+1].num=a[k+1].num;win[k/2+1].sco=a[k+1].sco;win[k/2+1].ab=a[k+1].ab;lose[k/2+1].num=a[k].num;lose[k/2+1].sco=a[k].sco;lose[k/2+1].ab=a[k].ab;}int w=1;int l=1;for (int j=1;j<=n;j++){if (win[w].sco>lose[l].sco){a[j].num=win[w].num;a[j].sco=win[w].sco;a[j].ab=win[w].ab;w++;continue;}else if (win[w].sco==lose[l].sco){if (win[w].num<lose[l].num){a[j].num=win[w].num;a[j].sco=win[w].sco;a[j].ab=win[w].ab;w++;}else {a[j].num=lose[l].num;a[j].sco=lose[l].sco;a[j].ab=lose[l].ab;l++;}continue;}a[j].num=lose[l].num;a[j].sco=lose[l].sco;a[j].ab=lose[l].ab;l++;}}printf("%d",a[q].num);return 0;}

暴力算法的话 很简单 每次进行sort排序 时间复杂度为o(nrlogn)

以下附上暴力算法

#include <cstdio>#include <cstdlib>#include <algorithm>using namespace std;struct xs{int score;int num;int power;bool operator < (const xs b)const{if(score == b.score)return num < b.num;else return score > b.score;}}a[100005];int N,R,Q;int main(){//freopen("swiss.in","r",stdin);//freopen("swiss.out","w",stdout);scanf("%d%d%d",&N,&R,&Q);for(int i = 1 ; i<= 2*N ;i++){scanf("%d",&a[i].score);a[i].num=i;}for(int i = 1 ; i<= 2*N ;i++){scanf("%d",&a[i].power);}for(int i = 1; i <=R ; i++){sort(a+1,a+1+2*N);for(int j = 1 ;j <= N ; j++){if(a[2*j].power<a[2*j-1].power)a[2*j-1].score++;elsea[2*j].score++;}}sort(a+1,a+1+2*N);printf("%d",a[Q].num);}


为了获得满分(装x)

很明显 每次比赛结束 都会产生有序的胜者组和败者组 

有序的原因是 在上一次排序基础上 不管是胜者组还是败者组 分数相对没有发生变化 也就是说 将比赛的结果重新分组 可以得到两个有序数组

有序数组又有什么用呢 

很明显 用归并排序 将胜者组和败者组重新排列

这样得到时间复杂度为o(n(logn+r))

成功AC




2019年8月22日 多云

距noip考试还有80天

❤Zy


原创粉丝点击