zoukankan      html  css  js  c++  java
  • 洛谷 p1309 瑞士轮

    题意:有很多选手,选手一开始有编号,初始积分和能力值,编号按输入顺序决定,输入完成后按积分排名,积分相同编号小的在前

    规定比R轮比赛,每轮比赛第一名与倒数第一比,第二名与倒数第二比,依次类推。能力值大的赢,赢的加一分,输的不加,每次比完一轮都要动态刷新排名。

    一开始,每次比完一轮我都会重新排个序,后面超时了,后面看到个更好的解法

    因为每次比完,所有的赢家之间的排名和所有的输家之间的排名是不会变的(因为如果一个赢家,它上一轮是输家,那么它即使这一轮赢了也不会比上一轮就是赢家且排他前面的赢家分数高,其它上一轮是输家这一轮是赢家的人也和它一样都只加了一分,相对位置不会改变,同理输家们也是一样)所以可以每次比拼结束后赢家加入赢家组,输家加入输家组,这样这两个组中已经组内有序了,接下来再归并这两个组就能得出排名,这样每次刷新排名所要的时间复杂度只有logn

    ps.当时不知道优先队列,现在发现估计可以用优先队列做,每次比拼一次更新完分数后再入队列

    #include<bits/stdc++.h>
    using namespace std;
    
    typedef struct pa{
      int num;
      int points;
      int ability;
    }Pa;
    Pa a[200500];
    
    bool cmp(Pa a, Pa b){
      if(a.points == b.points)
        return a.num < b.num;
      return a.points > b.points;
    }
    
    int main(){
      int n, r, q;
      cin >> n >> r >> q;
      n = n*2;
      for(int i=0; i<n; i++){
        cin >> a[i].points;
        a[i].num = i;
      }
      for(int i=0; i<n; i++)
        cin >> a[i].ability;
      sort(a, a+n, cmp);
    
      vector<Pa> winners;
      vector<Pa> losers;
      while(r--){
        winners.clear();
        losers.clear();
        for(int i=0; i<n; i+=2){
          if(a[i].ability > a[i+1].ability){
            a[i].points++;
            winners.push_back(a[i]);
            losers.push_back(a[i+1]);
          }else{
            a[i+1].points++;
            winners.push_back(a[i+1]);
            losers.push_back(a[i]);
          }
        }
          merge(winners.begin(), winners.end(), losers.begin(), losers.end(), a, cmp);
      }
      cout << a[q-1].num+1 << endl;
      return 0;
    }
  • 相关阅读:
    JVM 常用参数设置(针对 G1GC)
    Java 字符串常量池 及 intern 方法的使用
    JDK 1.8 Metaspace 详解
    JDK 1.8 MetaSpace(元空间)介绍及调优
    Git 统计代码行数
    王永庆传-读书笔记2
    王永庆传-读书笔记1
    董明珠:女人真想干点事,谁也拦不住
    esxi5.5安装nvme驱动
    nvme ssd的一些相关知识点
  • 原文地址:https://www.cnblogs.com/ssNiper/p/11253435.html
Copyright © 2011-2022 走看看