zoukankan      html  css  js  c++  java
  • 洛谷p1309瑞士轮(好题,理解归并排序本质)

    题目链接:https://www.luogu.org/problemnew/show/P1309

    不得不说,真是一道很nice的题。极大助于理解归并排序的本质(其实就是两个有序表的依次对比合并加入而已)(貌似库函数有个merge函数这里说了。。)

    快速排序快(适用于整个序列无序较多的情况下)

    归并排序(适用于序列大多有序的情况,更快。因为基本有序时sort还要打乱再排所以很浪费时间,归并就快多了每次顺序合并即可)

    对于本题,两个序列本来就是有序的(赢的一组,数的一组,肯定依次递降),就省去了归的步骤,直接进行并(合并)就行了,所以效率很高。

     1 #include <iostream>
     2 #include <string>
     3 #include <algorithm>
     4 #include <iomanip>
     5 #include <cstdio>
     6 #include <cstring>
     7 using namespace std;
     8 const int maxn=1e6+5;
     9 typedef long long ll;
    10 typedef unsigned long long ull;
    11 int n,r,q;
    12 struct px
    13 {
    14     int s;
    15     int w;
    16     int ii;
    17 }T[maxn],temp[maxn],a[maxn],b[maxn];
    18 bool cmp(px aa,px bb)
    19 {
    20     if(aa.s!=bb.s) return aa.s>bb.s;
    21     return aa.ii<bb.ii;
    22 }
    23 
    24 void MArray()
    25 {
    26     int i=1,j=1;
    27     int k=1;
    28 
    29     while(i<=n && j<=n)
    30     {
    31         if(a[i].s>b[j].s) temp[k++]=a[i++];
    32         else if(a[i].s<b[j].s) temp[k++]=b[j++];
    33         else
    34         {
    35             if(a[i].ii<b[j].ii) temp[k++]=a[i++];
    36             else temp[k++]=b[j++];
    37         }
    38     }
    39 
    40     while(i<=n) temp[k++]=a[i++];
    41     while(j<=n) temp[k++]=b[j++];
    42 
    43     for(int i=1;i<=k-1;i++) T[i]=temp[i];//更新原数组,为了下次再利用
    44 }
    45 
    46 
    47 int main()
    48 {
    49     ios::sync_with_stdio(false); cin.tie(0);
    50 
    51     cin>>n>>r>>q;
    52     for(int i=1;i<=n*2;i++)
    53     {
    54         cin>>T[i].s;
    55         T[i].ii=i;
    56     }
    57     for(int i=1;i<=n*2;i++) cin>>T[i].w;
    58 
    59     sort(T+1,T+1+n*2,cmp);
    60     //for(int i=1;i<=n*2;i++) cout<<T[i].ii<<' '<<T[i].s<<' '<<T[i].w<<endl;
    61     while(r--)
    62     {
    63         int p1=1,p2=1;
    64         for(int i=1;i<=n*2;i+=2)
    65         {
    66             if(T[i].w>T[i+1].w)
    67             {
    68                 T[i].s++;
    69                 a[p1++]=T[i];
    70                 b[p2++]=T[i+1];
    71             }
    72             else
    73             {
    74                 T[i+1].s++;
    75                 a[p1++]=T[i+1];
    76                 b[p2++]=T[i];
    77             }
    78         }
    79         MArray();
    80         //for(int i=1;i<=n*2;i++) cout<<T[i].ii<<' '<<T[i].s<<' '<<T[i].w<<endl;
    81     }
    82 
    83     cout<<T[q].ii<<endl;
    84 
    85     return 0;
    86 }

    完。

  • 相关阅读:
    OPENGLES 绘制纹理带黑圈pre-multiplying
    listview相关代码整理
    时区列表
    (迪杰斯特拉)Dijkstra算法
    全源最短路径(Floyd算法)
    go配置私有仓库 (go mod配置私有仓库)
    mingw+gcc 10.1下载
    线段树应用及概况
    清理docker常用命令
    minio设置永久访问链接
  • 原文地址:https://www.cnblogs.com/redblackk/p/9941367.html
Copyright © 2011-2022 走看看