• 洛谷 P1309 瑞士轮 & [NOIP2001普及组] (模拟、归并)


    传送门


    解题思路

    首先想暴力做法:

    每一次比赛前都sort一遍,然后两两比较,总复杂度为O(R*(n+2n*log(2n))),最大约为1.5*10^8,而且会跑满,所以需要优化。

    怎么优化呢?

    我们发现这样一条性质:

    假设排好序的序列为1,2,3,4(1>2>3>4)。这时进行比赛(1和2,3和4),假设1,4胜利,那么很显然,胜利后的积分1一定仍然>4,2一定仍然大于3。

    所以我们把它放到这道题中,用两个队列(普通队列),一个顺序存放每一轮比赛中胜利的队伍,一个顺序存放每一轮比赛中失败的队伍,很显然,这两个队列里的队伍积分是单调的。

    然后就可以利用归并排序中的归并操作,把它们归并到一个数组里,继续进行下一轮比赛。

    这样总复杂度为O(R*n),优化掉了一个log。

    AC代码

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstdio>
     4 #include<queue>
     5 using namespace std;
     6 const int maxn=200005;
     7 int n,r,q;
     8 struct node{
     9     int id,value,shili;
    10 }a[maxn];
    11 bool cmp(node a,node b){
    12     return a.value==b.value?a.id<b.id:a.value>b.value;
    13 }
    14 queue<node> q1,q2;
    15 int main()
    16 {
    17     cin>>n>>r>>q;
    18     for(int i=1;i<=2*n;i++) scanf("%d",&a[i].value);
    19     for(int i=1;i<=2*n;i++) scanf("%d",&a[i].shili);
    20     for(int i=1;i<=2*n;i++) a[i].id=i;
    21     sort(a+1,a+2*n+1,cmp);
    22     for(int i=1;i<=r;i++){
    23         for(int j=1;j<=n;j++){
    24             if(a[2*j-1].shili>a[2*j].shili){
    25                 a[2*j-1].value++;
    26                 q1.push(a[2*j-1]);
    27                 q2.push(a[2*j]);
    28             }else{
    29                 a[2*j].value++;
    30                 q1.push(a[2*j]);
    31                 q2.push(a[2*j-1]);
    32             }
    33         }
    34         int cnt=0;
    35         while(!q1.empty()&&!q2.empty()){
    36             node a1=q1.front();
    37             node a2=q2.front();
    38             if(a1.value>a2.value){
    39                 a[++cnt]=a1;
    40                 q1.pop();
    41             }else{
    42                 if(a1.value==a2.value&&a1.id<a2.id) a[++cnt]=a1,q1.pop();
    43                 else{            
    44                     a[++cnt]=a2;
    45                     q2.pop();
    46                 }
    47             }
    48         }
    49         while(!q1.empty()){
    50             a[++cnt]=q1.front();
    51             q1.pop();
    52         }
    53         while(!q2.empty()){
    54             a[++cnt]=q2.front();
    55             q2.pop();
    56         }
    57     }
    58     cout<<a[q].id;
    59     return 0;
    60 }

    //NOIP2001普及组 t3

  • 相关阅读:
    logging模块
    解压序列
    python碎片
    python碎片化
    [转]pycharm快捷键
    ios开发之自定义textView
    iOS 开发之字典写入文件
    iOS 开发之内存泄漏问题
    自己写小测试 内容:添加,删除,修改,详情,导出,上传文件,easyui tree树
    使用 jxl 实现复杂的excel 表格导出 java代码
  • 原文地址:https://www.cnblogs.com/yinyuqin/p/12110016.html
Copyright © 2020-2023  润新知