最近看到一场比赛,机制是真嚎
于是我就去洛谷看看,发现还有瑞士轮这个好东西(题目链接:P1309 [NOIP2011 普及组] 瑞士轮 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn))
但我看了看题解
我全不会
于是我寻思着,自己去做,发现弄来弄去是结构体和排序(sort真香)
因为我太懒了要节省时间,so,万能开头再定义结构
#include <bits/stdc++.h>
using namespace std;
struct xuanshou//创造一个结构体
{
int bianhao;//编号
int shili;//实力
int fengshu;//分数
} a[200020],win[200020],lose[200020];
接下来,就是主函数了
思路:输入——判定——合并——输出
那么第一步就是输入
int n,r,q;//n代表选手,r代表轮数,q代表要求的人第q名
cin>>n>>r>>q;
n=n*2;//代表总共有2*n名选手
for(int i=1; i<=n; i++)
{
a[i].bianhao=i;//输入编号
cin>>a[i].fengshu;//输入初始分数
}
for(int i=1; i<=n; i++)
{
cin>>a[i].shili;//输入实力
}
当然,如果要判定,就得请我们的sort来整理(虽然时间会炸,但我也没想到什么其他的了)
sort(a+1,a+n+1,cmp);//首先进行初始排序
靠,忘了定义cmp规则了 接下来我们来制定排序规则
题目说了,如若实力相等,那么看编号,也就说明不存在平局的观念,你看,思路就出来了,先判断编号在判断实力,即
bool cmp(xuanshou a,xuanshou b)//排序顺序
{
//先按照分数从大到小排序
if(a.fengshu==b.fengshu)//如果分数相同则按照编号从大到小排序
return a.bianhao<b.bianhao;//判断其编号,如若成立,执行下一步
else
return a.fengshu>b.fengshu;//判断分数
}
好,那么好,这样就可以开始下一步了,判定!!!
由于瑞士轮是多重赛,所以我们就可以用双循环来解决
当然,因为其要判断输赢,所以可以用下标解决(就是0,1,不懂去看:详解数组的下标_数组下标-CSDN博客)
那么过程就出来了
循环——判定实力——计算和计入输赢——结算——输出,即
for(int i=1; i<=r; i++)
{
int win1=1,lose1=1;//定义win数组和lose数组的下标
for(int j=1; j<=n; j=j+2)
if(a[j].shili>a[j+1].shili) //判断第一位选手实力是否大于第二位
{
//a[j]赢了,a[j+1]输了
a[j].fengshu++; //分数加一
win[win1]=a[j]; //放到win数组里
win1++; //下标加一,为了方便存储最后一名选手
lose[lose1]=a[j+1]; //输了放在lose数组中
lose1++; //下标加一,为了方便存储最后一名选手
}
else//如果第二位反杀了第一位
{
a[j+1].fengshu++; //逻辑同上
win[win1]=a[j+1];
win1++;
lose[lose1]=a[j];
lose1++;
}
merge(win+1,win+win1,lose+1,lose+lose1,a+1,cmp);
}//重新合并到a数组中,为了确保下一轮重新从a数组中进行分配
好了,最后万事具备,只欠东风,把输出一点,AC拿到手软,完整程序如下
#include <bits/stdc++.h>
using namespace std;
struct xuanshou//创造一个结构体
{
int bianhao;//编号
int shili;//实力
int fengshu;//分数
} a[200020],win[200020],lose[200020];
bool cmp(xuanshou a,xuanshou b)//排序顺序
{
//先按照分数从大到小排序
if(a.fengshu==b.fengshu)//如果分数相同则按照编号从大到小排序
return a.bianhao<b.bianhao;//判断其编号,如若成立,执行下一步
else
return a.fengshu>b.fengshu;//判断分数
}
int main()
{
int n,r,q;//n代表选手,r代表轮数,q代表要求的人第q名
cin>>n>>r>>q;
n=n*2;//代表总共有2*n名选手
for(int i=1; i<=n; i++)
{
a[i].bianhao=i;//输入编号
cin>>a[i].fengshu;//输入初始分数
}
for(int i=1; i<=n; i++)
{
cin>>a[i].shili;//输入实力
}
sort(a+1,a+n+1,cmp);//首先进行初始排序
for(int i=1; i<=r; i++)
{
int win1=1,lose1=1;//定义win数组和lose数组的下标
for(int j=1; j<=n; j=j+2)
if(a[j].shili>a[j+1].shili) //判断第一位选手实力是否大于第二位
{
//a[j]赢了,a[j+1]输了
a[j].fengshu++; //分数加一
win[win1]=a[j]; //放到win数组里
win1++; //下标加一,为了方便存储最后一名选手
lose[lose1]=a[j+1]; //输了放在lose数组中
lose1++; //下标加一,为了方便存储最后一名选手
}
else//如果第二位反杀了第一位
{
a[j+1].fengshu++; //逻辑同上
win[win1]=a[j+1];
win1++;
lose[lose1]=a[j];
lose1++;
}
merge(win+1,win+win1,lose+1,lose+lose1,a+1,cmp);
}//重新合并到a数组中,为了确保下一轮重新从a数组中进行分配
cout<<a[q].bianhao;//求第q名选手的编号
return 0;//大功告成
}
你还在看什么?写题目去啊!
(初二菜鸡第一次制作,大佬喷轻点)