NOIP2011普及组 瑞士轮
OJ地址:
https://www.luogu.org/problemnew/show/P1309
http://bailian.openjudge.cn/practice/4031/
- 总时间限制: 2000ms 单个测试点时间限制: 1000ms 内存限制: 65535kB
- 描述
-
【背景】
在双人对决的竞技性比赛,如乒乓球、羽毛球、国际象棋中,最常见的赛制是淘汰赛和循环赛。前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高。后者的特点是较为公平,偶然性较低,但比赛过程往往十分冗长。
本题中介绍的瑞士轮赛制,因最早使用于 1895 年在瑞士举办的国际象棋比赛而得名。它可以看作是淘汰赛与循环赛的折衷,既保证了比赛的稳定性,又能使赛程不至于过长。【问题描述】
2*N名编号为 1~2N的选手共进行 R轮比赛。每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名。 选手的总分为第一轮开始前的初始分数加上已参加过的所有比赛的得分和。总分相同的,约定编号较小的选手排名靠前。 每轮比赛的对阵安排与该轮比赛开始前的排名有关:第 1 名和第 2 名、第 3 名和第 4 名、……、第 2K – 1 名和第 2K名、…… 、第 2N – 1 名和第2N名,各进行一场比赛。每场比赛胜者得 1 分,负者得 0 分。也就是说除了首轮以外,其它轮比赛的安排均不能事先确定,而是要取决于选手在之前比赛中的表现。
现给定每个选手的初始分数及其实力值,试计算在 R 轮比赛过后,排名第 Q 的选手编号是多少。我们假设选手的实力值两两不同,且每场比赛中实力值较高的总能获胜。
输入
输入的第一行是三个正整数 N、R、Q,每两个数之间用一个空格隔开,表示有 2*N 名选手、R 轮比赛,以及我们关心的名次 Q。
第二行是 2*N个非负整数 s1, s2, …, s2N,每两个数之间用一个空格隔开,其中 si 表示编号为 i 的选手的初始分数。
第三行是 2*N个正整数 w1, w2, …, w2N,每两个数之间用一个空格隔开,其中 wi 表示编号为 i 的选手的实力值。
输出
输出只有一行,包含一个整数,即 R 轮比赛结束后,排名第 Q 的选手的编号。
样例输入
2 4 2
7 6 6 7
10 5 20 15
样例输出
1
提示
对于 30%的数据,1 ≤ N ≤ 100;
对于 50%的数据,1 ≤ N ≤ 10,000;
对于 100%的数据, 1 ≤ N ≤ 100,000, 1 ≤ R ≤ 50, 1 ≤ Q ≤ 2N, 0 ≤ s1, s2, …, s2N ≤ 108, 1 ≤ w1, w2, …, w2N ≤ 108。
算法分析:
参考https://blog.csdn.net/dengping_ss/article/details/49833557
对于这道题,最容易想到的算法恐怕就是直接模拟比赛过程,每轮比赛前都用快排排一次,然后再根据选手的实力值决定胜负。但是这样算下来,时间复杂度达到了O(R*(N*logN+N)),但实际动作的次数还要加一个常数倍,因为一共有2*N个人。
把数据范围看一下,就知道这种算法肯定是要超时的,因此只要还有时间,应该尝试更为高效的算法。
很容易可以知道,每轮比赛结束后,胜利者和失败者两个群体中内部的顺序是不会被打乱的。也就是说,第一轮比赛后每一对人中的胜利者拿来排序之后跟原来他们比赛前的顺序是一样的,当然失败者的一群人也一样。因此,很容易就想到之前那个算法为什么不够高效了,因为快排的效率高是针对随机的数列的,而这里每一轮比赛下来,有许多人(一半人)的相对顺序已经确定了。因此就想到了归并排序,这样,每一轮比赛后用O(N)的复杂度归并一次就好,而不用快排,那样会损失掉已有的信息。这样,估算下来,时间就够了。
值得注意的是:在第一轮比赛前,并不知道待比赛选手的排名,而这时又不可能得到任何已有的信息,因为本来直接给出的初始值s是无序的,所以这时应使用快排,而且要注意初始值相同的情况,但这里已经是细节,不是重点了。
另外,每一轮比赛过程中,两个人进行一场比赛后,这两人都应该分到两个临时数组(这两个数组分别代表胜利者群体和失败者群体)以便后续的归并操作。这个时候要特别注意:这一场比赛的两个人若是打平手了,那么两人都应该分到失败者群体,因为他们两人的积分都没有增加。
AC代码如下:
#include<stdio.h>
#include<stdlib.h>
struct person
{
int ID,s,w;//选手编号、分值、实力值
};
int cmp(const void *a,const void *b)
{
struct person *x,*y;
x=(struct person*)a;
y=(struct person*)b;
if(x->s > y->s) return -;
else if(x->s < y->s) return ;
else
{
if(x->ID > y->ID) return ;
else return ;
}
}
int main()
{
int N,R,Q;
struct person *a=NULL,*b=NULL,*c=NULL;
int i,j,NN,kb,kc,ib,ic; scanf("%d%d%d",&N,&R,&Q);
NN=*N;
a=(struct person *)malloc(sizeof(struct person)*NN);
b=(struct person *)malloc(sizeof(struct person)*NN);
c=(struct person *)malloc(sizeof(struct person)*NN); for(i=;i<NN;i++)
{
a[i].ID=i+;
scanf("%d",&a[i].s);
}
for(i=;i<NN;i++)
scanf("%d",&a[i].w);
qsort(a,NN,sizeof(a[]),cmp); for(i=;i<R;i++)
{
kb=kc=;
for(j=;j<NN;j=j+)//模拟一轮比赛
{
if(a[j].w>a[j+].w) { a[j].s++; b[kb++]=a[j]; c[kc++]=a[j+]; }
else if(a[j].w < a[j+].w) { a[j+].s++; b[kb++]=a[j+]; c[kc++]=a[j]; }
else
{
c[kc++]=a[j]; c[kc++]=a[j+];
}
} ib=ic=;
for(j=;ib<kb||ic<kc;j++)//一轮比赛完成以后,做一次归并操作使得a[]按积分降序排序
{
if(ic>=kc || (ib<kb&&b[ib].s>c[ic].s)||(ib<kb&&b[ib].s==c[ic].s&&b[ib].ID<c[ic].ID)) a[j]=b[ib++];
else a[j]=c[ic++];
}
}
printf("%d\n",a[Q-].ID);
free(a);
return ;
}
NOIP2011普及组 瑞士轮的更多相关文章
- [NOIP2011普及组]瑞士轮 JAVA实现
题目描述 2*N名编号为1~2N的选手共进行R轮比赛.每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名.选手的总分为第一轮开始前的初始分数加上已参加过的所有比赛的得分和.总分 ...
- NOIP2011普及组 瑞士环 保序性
题目链接:http://noi.openjudge.cn/ch0401/4363/ 分析:如果直接模拟,时间复杂度是O(r*nlogn)超时 然后我们发现每次一轮开始时,刚开始是保序的,然后我们可以把 ...
- NOIP2011 普及组 T3 洛谷P1309 瑞士轮
今天题做太少,放道小题凑数233 题目背景 在双人对决的竞技性比赛,如乒乓球.羽毛球.国际象棋中,最常见的赛制是淘汰赛和循环赛.前者的特点是比赛场数少,每场都紧张刺激,但偶然性较高.后者的特点是较为公 ...
- [NOIP2011] 普及组
数字反转 小模拟 #include<cstdio> #include<iostream> #include<cstring> using namespace std ...
- NOIP2011普及组 数字反转
题目OJ链接: http://codevs.cn/problem/1130/ https://www.luogu.org/problemnew/show/P1307 2011年NOIP全国联赛普及组 ...
- 【解题报告】瑞士轮(NOIP2011普及组T3)
[题外话:这道题吧……说实话我不太喜欢……因为卡快排.] 题目不贴了,就是给你一个赛制,然后各个选手的初始得分和能力值,问你进行R轮比赛之后第Q名的编号是多少(这个编号读进来就要算OYZ,初始快排的时 ...
- 【单调队列】Vijos P1771 瑞士轮 (NOIP2011普及组第三题)
题目链接: https://vijos.org/p/1771 题目大意: 给定2N个人(N<=100 000)和其初始分数.能力值(能力两两不同),比赛M次(M<=50),每次PK都是按分 ...
- noip2011普及组——统计单词数
统计单词数 时间限制:1 s 内存限制:128MB [问题描述]一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数.现在,请你编程实 ...
- noip2011普及组——数字反转
数字反转 时间限制:1s 内存限制:128MB[问题描述]给定一个整数,请将该数各个位上数字反转得到一个新数.新数也应满足整数的常见形式,即除非给定的原数为零,否则反转后得到的新数的最高位数字不应为零 ...
随机推荐
- Painting the Fence Gym - 101911E(构造)
There is a beautiful fence near Monocarp's house. The fence consists of nn planks numbered from left ...
- Sunscreen POJ - 3614(贪心)
To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with s ...
- linux(manjaro)磁盘迁移/opt /home
目录 1. 创建临时挂载点/opt, 并将分区挂载到临时挂载点上: 2. 切换单用户,将除了root用户之外的用户踢出 3. 将/opt目录下的所有内容拷贝到临时挂载点中,等待结束 4. 进入/et ...
- 可编辑DIV与移动端软键盘兼容性问题汇总
此文复现的所有兼容性问题均为以下情况: 1. 腾讯X5内核 2. 全屏webview 问题如下: 1. IOS12 中软键盘弹出导致页面顶部截断,并且无法恢复. 解决方法:添加交互事件,调用本地方法, ...
- List自定义排序(可多条件)
1:先建需要排序的属性Model package com.msqsoft.app.queuing.util; public class ListOrderByModel { private Strin ...
- Your ApplicationContext is unlikely to start due to a @ComponentScan of the default
问题:** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentScan of the defau ...
- Idea创建一个springboot多模块项目
一.创建空Maven项目 二.左边选择maven,右边可以什么不选,直接next: 三.填写artifactId,点击next直到finish 四.finish后,idea会生成如下结果模块,删除sr ...
- node 将本地项目docker化
vi test.sh docker rm -f kao3 || echo kao3 not exists;docker run -itd \--privileged=true \-v ~/logs:/ ...
- 解决 Excel2013打开提示 文件格式和扩展名不匹配。文件可能已损坏或不安全
有的时候打开xls文档时,会提示“文件格式和扩展名不匹配.文件可能已损坏或不安全.除非您信任其来源,否则请勿打开.是否仍要打开它?” 遇到这种情况,我们需要 1.win键+R键,打开“运行“,输入re ...
- BZOJ5207 : [Jsoi2017]隧道
若$\min(n,m)<\min(n+1,m-1)$,则考虑计算左边与右边不连通的概率,然后用$1$减去它得到答案. 若$\min(n,m)\geq \min(n+1,m-1)$,则考虑计算对偶 ...