• 暑假D1 T3 play(加速排序)


    题目大意

    这个位面存在编号为1~2N的2N个斗士,他们正为争夺斗士大餐展开R轮PVP,每个斗士i都有一个固有APM ai,和一个初始斗士大餐储量 bi。每轮开始前以及最后一轮结束之后,2N个斗士会重新按照各自斗士大餐的储量进行排序(斗士大餐储量相同时编号小的靠前),每轮中,第1名和第2名PVP,第3名和第4名PVP,……第2k-1名和第2k名PVP,第2N-1名和第2N名PVP。而每场一对一的PVP都非常无聊,总是两个斗士中APM高的获胜,另一方失败;或者APM相同的两方取得平手。每轮赛后获胜方获得2份斗士大餐,平均双方均获得1份斗士大餐。

    输入格式

    第一行两个整数N、R;
    第二行2N个整数,bi;
    第三行2N个整数, ai;

    输出格式

    2N个整数,R轮比赛后排名从小到大的各斗士编号;

    样例输入

    10 10
    0 10 49 24 7 1 64 8 52 81 4 9 40 17 52 17 40 0 97 77
    0 1 0 1 1 1 0 2 1 0 0 2 1 1 2 0 1 1 1 0

    样例输出

    19 10 20 7 15 9 13 17 3 4 14 12 8 2 16 5 6 18 11 1

    数据范围


    10%的数据:N≤10,R≤10,ai≤1e8,bi≤1e8
    30%的数据:N≤1e2,R≤60,ai≤1e8,bi≤1e8
    70%的数据:N≤1e4,R≤60,ai≤1e8,bi≤1e8
    100%的数据:N≤1e5,R≤60,ai≤1e8,bi≤1e8

    思路

    最初很容易可以想到用快排之后,直接模拟就好,复杂度O(R*logn)

    思考优化排序,将赢的、输的、平的分成三个队伍,对于每个队伍他bi增加的值相同,而一开始又有顺序,所以在队伍中仍有单调性。

    需要注意的是,在顶端的人bi是比较小的,所以在重新确定p数组时需要倒序插入。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn=200005;
    int n,r,top1,top2,top3;
    struct person{
        int a,b,id;
    }p[maxn],winner[maxn],loser[maxn],equel[maxn];
    
    template<class T>inline void read(T &x){
        x=0;char ch=getchar();
        while(!isdigit(ch)) ch=getchar();
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    }
    
    bool cmp(person s,person t){
        if(s.b==t.b) return s.id<t.id;
        return s.b>t.b;
    }
    
    bool cmp1(person s,person t){
        if(s.b==t.b) return s.id>t.id;
        return s.b<t.b;
    }
    
    int main(){
        freopen("play.in","r",stdin);
        freopen("play.out","w",stdout);
        scanf("%d%d",&n,&r);
        for(int i=1;i<=2*n;i++){
            scanf("%d",&p[i].b);
            p[i].id=i;
        }
        for(int i=1;i<=2*n;i++) scanf("%d",&p[i].a);
        sort(p+1,p+2*n+1,cmp);
        while(r--){
            for(int i=1;i<=2*n;i+=2)
             if(p[i].a>p[i+1].a){
                 p[i].b+=2;
                 winner[++top1]=p[i];
                 loser[++top2]=p[i+1];
             }
             else if(p[i].a<p[i+1].a){
                 p[i+1].b+=2;
                 winner[++top1]=p[i+1];
                 loser[++top2]=p[i];
             }
             else {
                 p[i].b++;p[i+1].b++;
                 equel[++top3]=p[i];
                 equel[++top3]=p[i+1];
             }
            for(int i=2*n;i;i--){
                if(top1){
                    if(top2){
                        if(cmp1(winner[top1],loser[top2])){
                          if(!top3) p[i]=winner[top1--];
                          else if(cmp1(winner[top1],equel[top3])) p[i]=winner[top1--];
                          else p[i]=equel[top3--];
                        }
                        else {
                            if(!top3) p[i]=loser[top2--];
                            else if(cmp1(loser[top2],equel[top3])) p[i]=loser[top2--];
                            else p[i]=equel[top3--];
                        }
                    } 
                    else if(!top3) p[i]=winner[top1--];
                    else if(cmp1(winner[top1],equel[top3])) p[i]=winner[top1--];
                    else p[i]=equel[top3--];
                } 
                else{
                    if(top2){
                        if(!top3) p[i]=loser[top2--];
                        else if(cmp1(loser[top2],equel[top3])) p[i]=loser[top2--];
                        else p[i]=equel[top3--];
                    }
                    else p[i]=equel[top3--];
                }
            }
        }
        for(int i=1;i<=2*n;i++) printf("%d ",p[i].id);
        return 0;
    }
    View Code
  • 相关阅读:
    维护IBM DB2数据库所应了解的底子内情知识6
    维护IBM DB2数据库所应了解的根本知识2
    教你疾速掌握DB2数据库中的相关呼吁1
    疾速把握IBM DB2数据库的常用操纵指令2
    维护IBM DB2数据库所应看法的根底常识1
    维护IBM DB2数据库所应了解的根蒂基本常识9
    维护IBM DB2数据库所应懂得的根基常识7
    维护IBM DB2数据库所应了解的根柢常识11
    疾速把握IBM DB2数据库的常用操纵指令3
    维护IBM DB2数据库所应领会的基本常识8
  • 原文地址:https://www.cnblogs.com/sto324/p/11160684.html
Copyright © 2020-2023  润新知