2011NOIP普及组真题 3. 瑞士轮

2024-05-04 16:28

本文主要是介绍2011NOIP普及组真题 3. 瑞士轮,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

线上OJ:

一本通:http://ybt.ssoier.cn:8088/problem_show.php?pid=1955

关键词句

“每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名”。这个句子告诉我们:
1、第一轮比赛之前需要先排一次序,不能直接上来就比;
2、每一轮比赛开始之前(排好序后),队伍是有序的

核心思想: 模拟 + 排序

本题可采用模拟,进行 r 轮后,输出排名第 q 的人即可

题解代码:
解法一、模拟 + 快速排序(60%分数)

排序采用默认的快速排序先试一遍模拟

//#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;const int N = 200010;
int n, r, q;struct Node
{int s, w, id;  // s为分数,w为实力值,id为选手编号
}a[N];bool cmp(Node x, Node y)
{if( x.s == y.s ) return x.id < y.id;  // 如果分数相同,id 小的排在前面else  return x.s > y.s; // 否则。分数高的排在前面
}int main()
{scanf("%d %d %d", &n, &r, &q);// 读入并初始化每个选手的分数、id,和实力值for(int i = 1; i <= 2 * n; i++){scanf("%d", &a[i].s);a[i].id = i;}for(int i = 1; i <= 2 * n; i++)  scanf("%d", &a[i].w);sort(a + 1, a + 1 + 2 * n, cmp);  // 按题意,每轮比赛前,先进行一次排序。故第一次比赛前的排序不能遗漏while(r--)  // 模拟 r 轮{for(int i = 1; i <= 2 * n; i += 2)  // 每一次比赛两组人a[i].w > a[i+1].w ? a[i].s++ : a[i+1].s++;  // 如果第 i 个人的实力值更大,则第 i 个人的分数++;否则,第 i+1 个人的分数++sort(a + 1, a + 1 + 2 * n, cmp); // 一轮结束后重新排序}printf("%d", a[q].id);return 0;
}

以上方法在开了O2的情况下,只能过80%的测试点。

解法二、模拟 + 桶排序(100%)

由于快速排序本身的时间复杂度是 O ( N l o g N ) O(NlogN) O(NlogN),r 轮就是 O ( r ∗ N l o g N ) O(r*NlogN) O(rNlogN),会超时。
仔细研读本题,会发现:
1、每一轮比赛(总共 r 轮)正式开始之前,队伍都是严格有序的
2、每一轮的 每一场 比赛都有 一个胜者一个败者。胜者都是+1分,败者都是+0分
3、这里考虑用 两个桶,一个桶装胜者,一个桶装败者
4、胜者都+1分,相当于没加;败者都+0分,也没加
所以胜者桶里保持着上一轮的排序败者桶里也保持着上一轮的排序
这样一来,每一轮结束后的排序就不再需要O(NlogN)的快速排序,而是直接拿两个桶的第一个数值进行比较,取最大值即可,时间复杂度变为O(N)。

代码如下:

#include <bits/stdc++.h>
using namespace std;const int N = 200010;
int n, r, q;struct Node
{int s, w, id;  // s为分数,w为实力值,id为选手编号
}a[N], win[N], lose[N];  // 桶排序:每一轮比赛后,赢的人放在赢的桶里,输的人放在输的桶里。这样每个桶内都是默认排好序的,桶内无需再排序bool cmp(Node x, Node y)
{if( x.s == y.s ) return x.id < y.id;  // 如果分数相同,id 小的排在前面else  return x.s > y.s; // 否则。分数高的排在前面
}void tsort()  // 将win和lose两个桶合并为新的a数组
{int k1 = 1, k2 = 1, i = 1;while( k1 <= n && k2 <= n ){if( cmp(win[k1], lose[k2]) )   a[i++] = win[k1++];else  a[i++] = lose[k2++];}while( k1 <= n ) a[i++] = win[k1++];while( k2 <= n ) a[i++] = lose[k2++];return;
}int main()
{scanf("%d %d %d", &n, &r, &q);// 读入并初始化每个选手的分数、id,和实力值for(int i = 1; i <= 2 * n; i++){scanf("%d", &a[i].s);a[i].id = i;}for(int i = 1; i <= 2 * n; i++)  scanf("%d", &a[i].w);sort(a + 1, a + 1 + 2 * n, cmp);  // 按题意,每轮比赛前,先进行一次排序。故第一次比赛前的排序不能遗漏while(r--)  // 模拟 r 轮{int k1 = 1, k2 = 1;for(int i = 1; i <= 2 * n; i += 2)  // 每一次比赛两组人{if(a[i].w > a[i+1].w) // 题目已保证实力值无相等的可能性{a[i].s++;win[k1++] = a[i];    // 赢的人放在赢的桶里。赢的人每人都 +1 分,所以赢的桶内无需再排序lose[k2++] = a[i+1]; // 输的人放在输的桶里,输的人每人都 +0 分,所以输的桶内也无需再排序}else{a[i+1].s++;win[k1++] = a[i+1];  // 赢的人放在赢的桶里。赢的人每人都 +1 分,所以赢的桶内无需再排序lose[k2++] = a[i];   // 输的人放在输的桶里,输的人每人都 +0 分,所以输的桶内也无需再排序}}tsort(); // 一轮结束后重新排序}printf("%d", a[q].id);return 0;
}

这篇关于2011NOIP普及组真题 3. 瑞士轮的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/959621

相关文章

笔试强训,[NOIP2002普及组]过河卒牛客.游游的水果大礼包牛客.买卖股票的最好时机(二)二叉树非递归前序遍历

目录 [NOIP2002普及组]过河卒 牛客.游游的水果大礼包 牛客.买卖股票的最好时机(二) 二叉树非递归前序遍历 [NOIP2002普及组]过河卒 题里面给的提示很有用,那个马的关系,后面就注意,dp需要作为long的类型。 import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息publ

找不同-第15届蓝桥省赛Scratch初级组真题第4题

[导读]:超平老师的《Scratch蓝桥杯真题解析100讲》已经全部完成,后续会不定期解读蓝桥杯真题,这是Scratch蓝桥杯真题解析第183讲。 如果想持续关注Scratch蓝桥真题解读,可以点击《Scratch蓝桥杯历年真题》并订阅合集,查阅教程更方便。 第15届蓝桥杯省赛已于2024年8月24日落下帷幕,编程题一共有5题,分别如下: 猪八戒落地 游乐场 画西瓜 找不同 消

信息学奥赛初赛天天练-83-NOIP2014普及组-基础题2-输入设备、输出设备、操作系统、二进制、整数除法、while、do while循环

1 NOIP 2014 普及组 基础题2 4 以下哪一种设备属于输出设备( ) A 扫描仪 B 键盘 C 鼠标 D 打印机 5 下列对操作系统功能的描述最为完整的是( ) A 负责外设与主机之间的信息交换 B 负责诊断机器的故障 C 控制和管理计算机系统的各种硬件和软件资源的使用 D 将没有程序编译成目标程序 11 下列各无符号十进制整数中,能用八位二进制表示的数中最大的是( ) A 296

免费SSL证书大全,加速普及网站实现HTTPS加密

免费SSL证书大全,加速普及网站实现HTTPS加密   SSL 证书用于加密 HTTP 协议,实现网站通过HTTPS加密协议访问。随着国内外各大网站实现全站 HTTPS 协议,以及搜索引擎对使用 HTTPS 协议网站的更加友好,加之互联网对数据和隐私安全的加强,网站添加 SSL 证书并实现 HTTPS 加密协议访问已经成为趋势和必然。 SSL证书大全​zzzjtd.com 而对于给网站添加

讨论运维监控工具的普及程度

在讨论运维监控工具的普及程度时,加入PIGOSS BSM产品的分析是非常有意义的,因为PIGOSS BSM是一款在中国市场具有一定影响力的运维监控工具。 PIGOSS BSM运维监控工具是一款综合性的IT运维监控解决方案,它能够对多层次的IT资源进行监测,包括但不限于性能监测、事件管理、报表管理等功能模块。PIGOSS BSM的一个独特之处在于其拓扑关联配置工具,这使得用户可以根据自身的I

P2239 [NOIP2014 普及组] 螺旋矩阵

P2239 [NOIP2014 普及组] 螺旋矩阵 50分 //O(n^2)复杂度,能算n<=10000的 #include <bits/stdc++.h>using namespace std;//row当前行, column当前列, left:左边界,righ:右边界,top:上边界,bottom:下边界 int n, x, y, ans, row=1, column=0, lef,

2020计算机挑战赛Java组真题

单选题 1.下列叙述哪些是错误的(). A.final 类不可以有子类 B.构造方法是类的一种特殊方法,其方法名必须与类名相同 C.抽象类可以用new运算符创建对象 D.内存回收程序不允许程序员直接释放内存2.下列叙述哪些是错误的(). A.abstract类不可以用new和构造函数定义对象 B.构造方法的返回值类型只能是void型 C.内存回收程序负责释放无用内存 D.Java类只能是单继承的

信息学奥赛初赛天天练-80-NOIP2015普及组-基础题5-错位排列、二叉树、完全二叉树、叶子节点、完全二叉树叶子节点

NOIP 2015 普及组 基础题5 21 重新排列 1234使得每一个数字都不在原来的位置上,一共有( )种排法 22 一棵结点数为 2015的二叉树最多有( )个叶子结点 2 相关知识点 1) 错位排列 考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。 n个元素的错排数记为D(n) 错排问题最早被尼古拉·伯努利和欧拉研究

蓝桥等级考1级c++组真题(选择)第一套(含答案解析)

纯个人整理,如有错误欢迎指正 1.以下关于C++程序描述错误的一项是() A.完整的程序必须有且仅有一个主函数,主函数的名字为main B.程序可以调用库函数,但必须要包含相对应的头文件 C.程序可以有注释行,注释行会被编译,但是不会被执行 D.程序的语句以分号结束,分号是c++程序不可缺少的组成部分 答案:C  解析: A. 程序有且只能有一个主函数,且名字必须为main B.

信息学奥赛初赛天天练-79-NOIP2015普及组-基础题4-即时通讯软件、二叉树遍历、前序遍历、中序遍历、后序遍历、算法时间复杂度

NOIP 2015 普及组 基础题4 11 下面哪种软件不属于即时通信软件( ) A QQ B MSN C 微信 D P2P 16 前序遍历序列与中序遍历序列相同的二叉树为( ) A 根结点无左子树 B 根结点无右子树 C 只有根结点的二叉树或非叶子结点只有左子树的二叉树 D 只有根结点的二叉树或非叶子结点只有右子树的二叉树 18 下列选项中不属于视频文件格式的是( ) A TXT B AV