• P1309 [NOIP2011 普及组] 瑞士轮


    尝试了几次,复杂度为(O(R(nlogn + n))),分别用了每轮快排和归并排,极限时间约为(50 * 200000 * 17),时间限制0.5s,TLE。

    思路:首先按照题目要求把运动员序列a排序,让他们按照(1 vs. 2, 3 vs. 4...)的方式比下去然后发现每一轮下来整个序列中赢的人的顺序仍然保持降序,输的人也保持降序,所以可以每一轮把赢的人和输的人分别放到两个序列中,然后再将它们降序合并到a里,这样的话,a仍然是降序的,复杂度为(O(n)),整体复杂度为(O(2 * Rn))

    #include<iostream>
    #include<vector>
    #include<algorithm>
    
    using namespace std;
    
    const int N = 1e5 + 10;
    
    struct node{
        int id, s, w;
        
        bool operator <(const node &n) const{
            if(s != n.s) return s > n.s;
            return id < n.id;
        }
    }a[N << 1];
    
    int n, m, q;
    
    int main(){
        cin >> n >> m >> q;
        
        n = n << 1;
        for(int i = 1; i <= n; i ++) cin >> a[i].s;
        for(int i = 1; i <= n; i ++) cin >> a[i].w;
        for(int i = 1; i <= n; i ++) a[i].id = i;
        sort(a + 1, a + 1 + n);
     
        while(m --){
            vector<node> win, lose;
            for(int i = 1; i < n; i += 2)
                if(a[i].w > a[i + 1].w){ 
                    a[i].s ++;
                    win.push_back(a[i]);
                    lose.push_back(a[i + 1]);
                }else{
                    a[i + 1].s ++;
                    win.push_back(a[i + 1]);
                    lose.push_back(a[i]);
                }
            int i = 0, j = 0, k = 0;
            while(i < win.size() && j < lose.size()){
                if(win[i] < lose[j]) a[++ k] = win[i ++];
                else a[++ k] = lose[j ++];
            }
            while(i < win.size()) a[++ k] = win[i ++];
            while(j < lose.size()) a[++ k] = lose[j ++];
        }
        
        cout << a[q].id << endl;
        
        return 0;
    }
    
  • 相关阅读:
    基本数据类型转换
    java8新增的日期时间包
    算法之冒泡排序
    基本数据类型
    spring入门
    JiuDuOj——1020
    JiuDuOj——1051
    2015.11.26——Accelerated C++
    POJ2681——求字符串长度
    POJ1017——装箱问题
  • 原文地址:https://www.cnblogs.com/tomori/p/15238874.html
Copyright © 2020-2023  润新知