• codevs 1170 双栈排序


    1170 双栈排序

     

    2008年NOIP全国联赛提高组

     时间限制: 1 s
     空间限制: 128000 KB
     
    题目描述 Description

    Tom最近在研究一个有趣的排序问题。如图所示,通过2个栈S1和S2,Tom希望借助以下4种操作实现将输入序列升序排序。

    操作a

    如果输入序列不为空,将第一个元素压入栈S1

    操作b

    如果栈S1不为空,将S1栈顶元素弹出至输出序列

    操作c

    如果输入序列不为空,将第一个元素压入栈S2

    操作d

    如果栈S2不为空,将S2栈顶元素弹出至输出序列

    如果一个1~n的排列P可以通过一系列操作使得输出序列为1,2,…,(n-1),n,Tom就称P是一个“可双栈排序排列”。例如(1,3,2,4)就是一个“可双栈排序序列”,而(2,3,4,1)不是。下图描述了一个将(1,3,2,4)排序的操作序列:<a,c,c,b,a,d,d,b>

    当然,这样的操作序列有可能有几个,对于上例(1,3,2,4),<a,c,c,b,a,d,d,b>是另外一个可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。

    输入描述 Input Description

    输入的第一行是一个整数n。

    第二行有n个用空格隔开的正整数,构成一个1~n的排列。

    输出描述 Output Description

    输出共一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。

    样例输入 Sample Input

    【样例1】

    4

    1 3 2 4

    【样例2】

    4

    2 3 4 1

    【样例3】

    3

    2 3 1

    样例输出 Sample Output

    【样例1】

    a b a a b b a b

    【样例2】

    0

    【样例3】

    a c a b b d

    数据范围及提示 Data Size & Hint

    30%的数据满足: n<=10

    50%的数据满足: n<=50

    100%的数据满足: n<=1000

    /*
    对于一个栈 给一个序列可以很容易判断按规定输出
    现在有如下性质
    当存在i<j<k并且a[k]<a[i]<a[j]
    在a[k]出栈之前a[i]和a[j]不能出栈
    而a[i]比a[j]先来 但要先出不符合栈的性质 所以a[i],a[j]肯定不在一个栈中
    当出现a,b,c都不在同一个栈那么不能实现双栈排序 输出0
    标记好后只需看1和2两个栈怎么进出即可
    注意字典序
    又一遍打错RMQ
    QAQ......
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<stack>
    #define maxn 1010
    using namespace std;
    int n,topt,flag;
    int a[maxn],color[maxn];
    int first[maxn];
    int f[maxn][15];
    struct edge
    {
        int to;
        int next;
    }e[maxn*maxn*2];
    stack<int>A,B;
    void add(int x,int y)
    {
        topt++;
        e[topt].to=y;
        e[topt].next=first[x];
        first[x]=topt;
    }
    void prepare()
    {
        for(int j=1;j<=12;j++)
            for(int i=1;i+(1<<j)-1<=n;i++)
                f[i][j]=min(f[i][j-1],f[i+(1<<j-1)][j-1]);
    }
    int query(int l,int r)
    {
        int k=log(r-l+1)/log(2);
        return min(f[l][k],f[r-(1<<k)+1][k]);
    }
    void dfs(int x,int p)
    {
        int t;
        if(p==1) t=2;
        else t=1;
        if(color[x]&&color[x]!=p){flag=1;return;}
        if(color[x])return;
        color[x]=p;
        for(int i=first[x];i;i=e[i].next)
        {
            int to=e[i].to;
            dfs(to,t);
            if(flag)return;
        }
    }
    int main()
    {
        freopen("twostack.in","r",stdin);
        freopen("twostack.out","w",stdout);
        scanf("%d",&n);
        memset(f,127/3,sizeof(f));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            f[i][0]=a[i];
        }
        prepare();
        for(int i=1;i<n;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                int r=query(j+1,n);
                if(r<a[i]&&a[i]<a[j])
                add(i,j),add(j,i);
            }
        }
        for(int i=1;i<=n;i++)
        {
            if(!color[i])
            {
                dfs(i,1);
                if(flag)break;
            }
        }
        if(flag){printf("0
    ");return 0;}
        int now=1;
        for(int i=1;i<=n;i++)
        {
            if(color[i]==2)
            {
                B.push(a[i]);
                printf("c ");
                while((!B.empty()&&B.top()==now)||(!A.empty()&&A.top()==now))
                {
                    if(!B.empty()&&B.top()==now)
                    {
                        B.pop();now++;
                        printf("d ");
                    }
                    if(!A.empty()&&A.top()==now)
                    {
                        A.pop();now++;
                        printf("b ");
                    }
                }
            }
            else
            {
                A.push(a[i]);
                printf("a ");
                while((!B.empty()&&B.top()==now)||(!A.empty()&&A.top()==now))
                {
                    if(!B.empty()&&B.top()==now)
                    {
                        B.pop();now++;
                        printf("d ");
                    }
                    if(!A.empty()&&A.top()==now)
                    {
                        A.pop();now++;
                        printf("b ");
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    程序经理_产品经理_项目经理
    github上排名靠前的java项目之_storm
    垂直型与水平型电子商务网站的理解
    关于驱动更新的一点学习
    Balanced Binary Tree
    Gray Code
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Maximum Depth of Binary Tree
    Next Permutation
  • 原文地址:https://www.cnblogs.com/dingmenghao/p/6003772.html
Copyright © 2020-2023  润新知