首页 > 其他分享 >4866: 瑞士轮 归并排序

4866: 瑞士轮 归并排序

时间:2023-08-16 21:55:30浏览次数:27  
标签:分数 归并 比赛 int win 选手 lose 排序 4866

描述

 

 

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的选手的实力值。

1 ≤ N ≤ 100,000,1 ≤ R ≤ 50,1 ≤ Q ≤ 2N,0 ≤ s1, s2, …, s2N≤108,1 ≤w1, w2 , …, w2N≤ 108

1 ≤ N ≤ 100,000,1 ≤ R ≤ 50,1 ≤ Q ≤ 2N,0 ≤ s_1, s_2, …, s_{2N}≤10^8,1 ≤w_1, w_2 , …, w_{2N}≤ 10^

 

 

输出

 

 

输出只有一行,包含一个整数,即R轮比赛结束后,排名第Q的选手的编号。

 

 

样例输入

 

2 4 2
7 6 6 7
10 5 20 15

样例输出

1

▶用数组依次表示选手编号,当前得分,实力值

▶编写cmp函数,先对选手按照初始分数从大到小排列,分数相同者编号从小到大排列

▶每轮赛后用归并排序(merge函数)对所有选手进行排序。分成胜者组和败者组,此时两个数组一定都按照分数由大到小排列,因此比较两数组的最大值,分数高者加进总序列,分数低者继续和另一个数组的次高值比较,分数高者再加进总序列。直到两个数组的元素都加进总序列。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e6+10,inf = 0x3f3f3f3f;
int n,r,q;
int s[N],w[N]; //s初识分数,w实力 
int a[N],win[N],lose[N];//a编号, win每局胜利下标,lose失败下标
bool cmp(int x,int y)
{
    if(s[x]==s[y])return x<y;
    return s[x]>s[y];
} 
void split()
{
    win[0] = lose[0] = 0;
    for(int i = 1; i <= n; i+=2) //相邻选手比赛每次+2
    {
        if(w[a[i]] > w[a[i+1]])
        {
            s[a[i]]++;
            win[++win[0]] = a[i];
            lose[++lose[0]] = a[i+1];
        }
        else
        {
            s[a[i+1]]++;
            win[++win[0]] = a[i+1];
            lose[++lose[0]] = a[i];
        }
    }
}
void merge() //归并,使有序的win,lose归并到a
{
    int i,j;
    i = j = 1, a[0] = 0;//k记录a[]中有多少个数
    while(i <= win[0] && j<=lose[0])
    {
        if(cmp(win[i], lose[j]))a[++a[0]] = win[i++];
        else a[++a[0]] = lose[j++];
    } 
    while(i <= win[0])a[++a[0]] = win[i++];//若败者组已全部加进序列,胜者组有剩则依次加进总序列
    while(j <= lose[0]) a[++a[0]] = lose[j++];//若胜者组已全部加进序列,败者组依次进总序列
} 
int main()
{
    cin >> n >> r >> q; n*=2;
    for(int i = 1; i <= n; i++) a[i] = i;
    for(int i = 1; i <= n; i++) cin >> s[i];
    for(int i = 1; i <= n; i++) cin >> w[i];
    sort(a + 1, a + n + 1, cmp); //将选手按照初识分数降序
    while(r--)
    {
        split(); //先拆分 
        merge(); //后合并 
    } 
    cout << a[q];
     return 0;
}

 

标签:分数,归并,比赛,int,win,选手,lose,排序,4866
From: https://www.cnblogs.com/jyssh/p/17636295.html

相关文章

  • 5708: 逆序对 归并排序
    描述  给定 一个序列,求其逆序对的总数。所谓逆序对是指:序列a中存在两个元素a[i]和a[j],满足 i<j 且a[i]>a[j],则a[i]和a[j]为一个逆序对。  输入  第一行为正整数n(n<=100000)。第二行有n个正整数,最大不超过1000000。  输出  输出逆序对的总数。......
  • Java中List排序的4种方法
    在开发ERP或电商系统中,经常会遇到内容加密,生成签名,展示页面列表等功能场景,这个时候我们需要在Java程序中对List集合进行排序操作。排序的常见方法有以下4种:使用Comparable进行排序;使用Comparator进行排序;JDK8以上的环境,可以使用Stream流进行排排序;JD......
  • 冒泡排序
    冒泡排序-时间复杂度为O(n2)publicclassDemo{publicstaticvoidmain(String[]args){int[]a={3,23,12,3,423,22,4,534,66,34};System.out.println(Arrays.toString(sort(a)));}//冒泡排序//1比较数组中,两个相邻的元素,如......
  • 计数排序(Python)
    defcounting(data):"data里的value作为计数数组counts的index,然后把counts的value转换成data的index"#计数列表,存储每个值有多少个,以data的值作为索引,所以数组长度以最大值+1为准counts=[0foriinrange(max(data)+1)]#同时给数组赋初值0,等会逐个计数......
  • MySQL8.0 JSON的对比、排序和索引
    (目录)JSON的对比和排序JSON值可以通过=,<,<=,>,>=,<>,!=,<=>操作符来进行对比JSON不支持BETWEEN,IN(),GREATEST(),LEAST(),可以通过将JSON转换为其他数据类型来使用这些操作符。JSON值的对比在两个级别上进行,先进行数据类型的对比,如果类型相同,再进行值的对比。类型可以......
  • 冒泡排序
    #include<iostream>usingnamespacestd;intmain(){intn;cin>>n;inta[n];for(inti=0;i<n;i++){ cin>>a[i]; }for(inti=1;i<n;i++){for(intj=1;j<=n-i;j++){if(a[j-1]<a[j]){......
  • 基数排序
    博客地址:https://www.cnblogs.com/zylyehuo/#-*-coding:utf-8-*-#O(n)O(kn)#NBO(nlogn)importrandomdefpartition(li,left,right):tmp=li[left]whileleft<right:whileleft<rightandli[right]>=tmp:#从右面找比tmp小的数......
  • 【数据结构】排序2 交换排序
    交换排序就是基于比较交换的排序。主要讲两种交换排序算法:冒泡排序和快速排序。冒泡排序比较简单一般不会单独考察,重点考察的是快速排序的内容。1.冒泡排序基本算法思想:对于每趟排序,从后往前两两比较,如果为逆序则进行交换,这样很显然不能一趟就得到正确的序列,但是每次都会把最......
  • [MAUI]在.NET MAUI中实现可拖拽排序列表
    .NETMAUI中提供了拖放(drag-drop)手势识别器,允许用户通过拖动手势来移动控件。在这篇文章中,我们将学习如何使用拖放手势识别器来实现可拖拽排序列表。在本例中,列表中显示不同大小的磁贴(Tile)并且可以拖拽排序。使用.NETMAU实现跨平台支持,本项目可运行于Android、iOS平台。创......
  • 希尔排序
    博客地址:https://www.cnblogs.com/zylyehuo/#_*_coding:utf-8_*_importrandomdefinsert_sort_gap(li,gap):foriinrange(gap,len(li)):#i表示摸到的牌的下标tmp=li[i]j=i-gap#j指的是手里的牌的下标whilej>=0and......