• codevs 1170 双栈排序


    /*
    好题啊 好题啊
    而然还是看了一眼题解啊
    有那么一点思路 但是离写出代码还很远
    考虑必须分开放倒两个栈里的情况
    即存在i<j<k 有 a[k]<a[i]<a[j] 这里RMQ n*n搞一下 
    那如果出现 a b 不在一块 b c 不在一块 a c 不在一块
    那么两个栈显然办不了了
    所以嘛 因为只有俩栈 染色吧那就
    染完判一下输出0的情况
    同时不相邻的那些的块块 按字典序染
    然后就就模拟一下 就像个普通的火车进站类似的题
    只不过有两个栈
    注意当可以进2出1的时候 先出1 这样字典序小 
    (感觉到了字典序深深地恶意) 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 1010
    using namespace std;
    int n,m,a[maxn],num,head[maxn],color[maxn],mx[maxn][25],P[maxn],falg;
    int s1[maxn],top1,s2[maxn],top2;
    struct node{
        int v,pre;
    }e[maxn*maxn*2];
    int max(int x,int y){
        return x>y?x:y;
    }
    void Add(int from,int to){
        num++;e[num].v=to;
        e[num].pre=head[from];
        head[from]=num;
    }
    void Insert(){
        memset(mx,127/3,sizeof(mx));
        for(int i=1;i<=n;i++)mx[i][0]=a[i];
        for(int j=1;j<=20;j++)
            for(int i=1;i+(1<<j)-1<=n;i++)
                mx[i][j]=min(mx[i][j-1],mx[i+(1<<j-1)][j-1]);
    }
    void Get(){
        for(int i=1;i<=n;i++)
            for(int j=0;j<=20;j++)
                if((1<<j)>i){
                    P[i]=j-1;break;
                }
    }
    int Query(int l,int r){
        int k=P[r-l+1];
        return min(mx[l][k],mx[r-(1<<k)+1][k]);
    }
    int Dfs(int x){
        for(int i=head[x];i;i=e[i].pre){
            int v=e[i].v;
            if(color[v]==0){
                color[v]=3-color[x];
                if(!Dfs(v))return 0;
            }
            else if(color[v]==color[x])return 0;
        }
        return 1;
    }
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        Insert();Get();
        for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++){
                if(a[i]>a[j])continue;
                int mx=Query(j+1,n);
                if(mx<a[i])Add(a[i],a[j]),Add(a[j],a[i]);
            }
        for(int i=1;i<=n;i++)
            if(color[i]==0){
                color[i]=1;
                if(!Dfs(i)){falg=1;break;}
            }
        if(falg==1){printf("0
    ");return 0;}
        int now=1;
        for(int i=1;i<=n;i++){
            if(color[a[i]]==1){
                if(a[i]==now){printf("a b ");now++;}
                else{
                    while(a[i]>s1[top1]&&top1){
                        top1--;printf("b ");
                    }
                    s1[++top1]=a[i];printf("a ");
                }
            }
            else {
                if(a[i]==now){printf("c d ");now++;}
                else{
                    while(a[i]>s2[top2]&&top2){
                        top2--;printf("b ");
                    }
                    while(s1[top1]==now){
                        top1--;printf("b ");now++;
                    }
                    s2[++top2]=a[i];printf("c ");
                }
            }
        }
        for(int i=now;i<=n;i++){
            while(top1&&i==s1[top1]){
                top1--;printf("b ");
            }
            while(top2&&i==s2[top2]){
                top2--;printf("d ");
            }
        }
        return 0;
    }
  • 相关阅读:
    Linux文件属性之用户和组基础知识介绍
    企业案例-文件删除企业生产故障模拟重现(未完成待续)
    Linux文件属性之Linux文件删除重要原理详解
    Linux文件属性之软硬连接知识深度详解
    Linux文件权限基础知识
    Linux文件属性拓展知识
    Linux 文件和目录的属性及权限
    linux优化之优化开机自启动服务
    (企业面试)描述Linux系统的启动过程?
    Linux企业面试题(一)
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5947445.html
Copyright © 2020-2023  润新知