洛谷 P1309 [NOIP 2011 普及组] 瑞士轮

张开发
2026/4/4 6:27:57 15 分钟阅读
洛谷 P1309 [NOIP 2011 普及组] 瑞士轮
题目背景在双人对决的竞技性比赛如乒乓球、羽毛球、国际象棋中最常见的赛制是淘汰赛和循环赛。前者的特点是比赛场数少每场都紧张刺激但偶然性较高。后者的特点是较为公平偶然性较低但比赛过程往往十分冗长。本题中介绍的瑞士轮赛制因最早使用于 1895 年在瑞士举办的国际象棋比赛而得名。它可以看作是淘汰赛与循环赛的折中既保证了比赛的稳定性又能使赛程不至于过长。题目描述2×N 名编号为 1∼2×N 的选手共进行 R 轮比赛。每轮比赛开始前以及所有比赛结束后都会按照总分从高到低对选手进行一次排名。选手的总分为第一轮开始前的初始分数加上已参加过的所有比赛的得分和。总分相同的约定编号较小的选手排名靠前。每轮比赛的对阵安排与该轮比赛开始前的排名有关第 1 名和第 2 名、第 3 名和第 4 名、……、第 2×K−1 名和第 2×K 名、…… 、第 2×N−1 名和第 2×N 名各进行一场比赛。每场比赛胜者得 1 分负者得 0 分。也就是说除了首轮以外其它轮比赛的安排均不能事先确定而是要取决于选手在之前比赛中的表现。现给定每个选手的初始分数及其实力值试计算在 R 轮比赛过后排名第 Q 的选手编号是多少。我们假设选手的实力值两两不同且每场比赛中实力值较高的总能获胜。输入格式第一行是三个正整数 N,R,Q每两个数之间用一个空格隔开表示有 2×N 名选手、R 轮比赛以及我们关心的名次 Q。第二行是 2×N 个非负整数 s1​,s2​,…,s2×N​每两个数之间用一个空格隔开其中 si​ 表示编号为 i 的选手的初始分数。第三行是 2×N 个正整数 w1​,w2​,…,w2×N​每两个数之间用一个空格隔开其中 wi​ 表示编号为 i 的选手的实力值。输出格式一个整数即 R 轮比赛结束后排名第 Q 的选手的编号。输入输出样例输入 #1复制2 4 2 7 6 6 7 10 5 20 15输出 #1复制1说明/提示【样例解释】【数据范围】对于 30% 的数据1≤N≤100对于 50% 的数据1≤N≤10000对于 100% 的数据1≤N≤105,1≤R≤50,1≤Q≤2×N,0≤s1​,s2​,…,s2×N​≤108,1≤w1​,w2​,…,w2×N​≤108。noip2011 普及组第 3 题。#includebits/stdc.h using namespace std; const int N2e510; int n,r,q; struct node{ int s,w,id; }a[N]; node x[N],y[N];//胜利组 失败组 bool cmp(node r,node u) { if(r.su.s) return r.idu.id; return r.su.s; } void merge() { //合并两个有序数组 int i1; int cur11,cur21; while(cur1ncur2n) { if(x[cur1].sy[cur2].s||(x[cur1].sy[cur2].sx[cur1].idy[cur2].id)) { a[i]x[cur1]; }else { a[i]y[cur2]; } } while(cur1n) a[i]x[cur1]; while(cur2n) a[i]y[cur2]; } int main() { cinnrq; for(int i1;inn;i) { cina[i].s; a[i].idi; } for(int i1;inn;i) { cina[i].w; } sort(a1,a1nn,cmp); while(r--) { int pos1; for(int i1;inn;i2) { if(a[i].wa[i1].w) { a[i].s; x[pos]a[i]; y[pos]a[i1]; }else{ a[i1].s; x[pos]a[i1]; y[pos]a[i]; } pos; } merge(); } couta[q].idendl; return 0; }

更多文章