蒻苟经过一个小时的鏖战终于拿下这道题
#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++;
else
a[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