zoukankan      html  css  js  c++  java
  • NOIP2011普及组:瑞士轮

    题目来源:https://www.luogu.org/problem/show?pid=1309

    题目描述:

    2*N 名编号为 1~2N 的选手共进行R 轮比赛。每轮比赛开始前,以及所有比赛结束后,都会按照总分从高到低对选手进行一次排名。选手的总分为第一轮开始前的初始分数加上已参加过的所有比赛的得分和。总分相同的,约定编号较小的选手排名靠前。

    每轮比赛的对阵安排与该轮比赛开始前的排名有关:第1 名和第2 名、第 3 名和第 4名、……、第2K – 1 名和第 2K名、…… 、第2N – 1 名和第2N名,各进行一场比赛。每场比赛胜者得1 分,负者得 0 分。也就是说除了首轮以外,其它轮比赛的安排均不能事先确定,而是要取决于选手在之前比赛中的表现。

    现给定每个选手的初始分数及其实力值,试计算在R 轮比赛过后,排名第 Q 的选手编号是多少。我们假设选手的实力值两两不同,且每场比赛中实力值较高的总能获胜。

    解析:这题可以考虑排序,第一轮直接排序,求出结果。接着我们注意到,每一轮必定会产生n个胜利者得分,n个失败者不得分,这两组各自内部的排名是不变的。我们可以考虑把他们分开处理。则只需要合并的操作。时间复杂度为O(nlogn+n*r)

    代码:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<cstdlib>
     6 #include<algorithm>
     7 #include<cctype>
     8 #include<iomanip>
     9 using namespace std;
    10 int n,r,q;
    11 struct node{
    12     int w,s;
    13     int ni;
    14 }wh[200001],win[200001],lose[200001];
    15 bool cmp(node a,node b){
    16     if(a.s==b.s) return a.ni<b.ni;
    17     return a.s>b.s;
    18 }
    19 void work(int n,int r){
    20     int i,j,k;
    21     for(j=1;j<=r;j++){
    22         int wi=1,lo=1;
    23         for(i=1;i<=n;i=i+2){
    24             if(wh[i].w>wh[i+1].w){
    25                 win[wi]=wh[i];
    26                 wi++;
    27                 lose[lo]=wh[i+1];
    28                 lo++;
    29             }
    30             if(wh[i].w<wh[i+1].w){
    31                 win[wi]=wh[i+1];
    32                 wi++;
    33                 lose[lo]=wh[i];
    34                 lo++;
    35             }
    36         }
    37         wi--;
    38         lo--;
    39         for(i=1;i<=n/2;i++)  win[i].s++;
    40         int x=1,y=1;
    41         i=1;
    42         while(x<=n/2 && y<=n/2){
    43             if(win[x].s>lose[y].s){
    44                 wh[i++]=win[x++];
    45             }
    46             if(win[x].s<lose[y].s){
    47                 wh[i++]=lose[y++];
    48             }
    49             if(win[x].s==lose[y].s && win[x].ni<lose[y].ni){
    50                 wh[i++]=win[x++];
    51             }
    52             if(win[x].s==lose[y].s && win[x].ni>lose[y].ni){
    53                 wh[i++]=lose[y++];
    54             }
    55         }
    56         if(x>n/2)
    57           while(y<=n/2)
    58             wh[i++]=lose[y++];
    59         else
    60           while(x<=n/2)
    61             wh[i++]=win[x++];
    62     }
    63 }
    64 int main()
    65 {
    66     int i,j,k;
    67     cin>>n>>r>>q;
    68     n*=2;
    69     for(i=1;i<=n;i++){
    70       cin>>wh[i].s;
    71       wh[i].ni=i;
    72     }
    73     for(i=1;i<=n;i++)
    74       cin>>wh[i].w;
    75     sort(wh+1,wh+n+1,cmp);
    76     work(n,r);
    77     cout<<wh[q].ni<<endl;
    78     return 0;
    79 }
  • 相关阅读:
    运维岗春招--part2
    python 题库|刷题
    leetcode刷题
    运维面经汇总
    python自动化运维阅读笔记
    Python编程汇总
    old_boy 运维学习-第一期
    团队博客作业-Week3
    个人对final发布产品的排名
    各组对final发布产品的排名
  • 原文地址:https://www.cnblogs.com/lazytear/p/6867492.html
Copyright © 2011-2022 走看看