zoukankan      html  css  js  c++  java
  • [NOIP2008] 提高组 洛谷P1155 双栈排序

    题目描述

    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希望知道其中字典序最小的操作序列是什么。

    输入输出格式

    输入格式:

    输入文件twostack.in的第一行是一个整数n。

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    【输入样例1】
    4
    1 3 2 4
    【输入样例2】
    4
    2 3 4 1
    【输入样例3】
    3
    2 3 1
    
    
    输出样例#1:
    【输出样例1】
    a b a a b b a b
    【输出样例2】
    0
    【输出样例3】
    a c a b b d

    说明

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

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

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

    考虑单栈排序:如果有三个元素a[i]<a[j] && a[i]>a[k],且它们的顺序 i<j<k,a[i]出栈以后a[j]才能进栈,a[k]出栈以后a[i]才能出栈,显然无法满足要求。

    所以,如果三个数满足以上条件,它们是不能同进一个栈的。

    先n downto 1倒推出每个数后面最小的数,作为a[k],然后枚举a[i],a[j],若符合上述条件,则在i,j之间连边,表示它们不能进同一个栈。

    之后进行二分图染色,如果遇到颜色矛盾,说明不能把冲突的点对分成两组,也就是问题无解。

    如果没有冲突,则问题有解,模拟即可。

     1 /*by SilverN*/
     2 #include<iostream>
     3 #include<algorithm>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<stack>
     8 using namespace std;
     9 const int mxn=12000;
    10 struct edge{
    11     int v;
    12     int nxt;
    13 }e[mxn];
    14 int hd[mxn],mct=0;
    15 void add_edge(int u,int v){
    16     e[++mct].v=v;e[mct].nxt=hd[u];hd[u]=mct;
    17     return;
    18 }
    19 int a[mxn],n;
    20 int mini[mxn];
    21 int c[mxn];
    22 int ans[mxn],t=0;
    23 bool dfs(int u){
    24     if(c[u]==-1)c[u]=0;
    25     for(int i=hd[u];i;i=e[i].nxt){
    26         int v=e[i].v;
    27         if(c[v]==-1){
    28             c[v]=c[u]^1;
    29             if(!dfs(v))return 0;
    30         }
    31         else{
    32             if(c[v]==c[u])return 0;
    33         }
    34     }
    35     return 1;
    36 }
    37 stack<int>tp1,tp2;
    38 int main(){
    39     memset(c,-1,sizeof c);
    40     int i,j;
    41     scanf("%d",&n);
    42     mini[n+1]=0x3f3f3f;
    43     for(i=1;i<=n;i++)scanf("%d",&a[i]);
    44     for(i=n;i;i--) mini[i]=min(mini[i+1],a[i]);
    45     for(i=1;i<n;i++)
    46      for(j=i+1;j<=n;j++){
    47          if(a[i]<a[j] && a[i]>mini[j+1]){
    48              add_edge(j,i);
    49              add_edge(i,j);
    50          }
    51      }
    52     for(i=1;i<=n;i++)
    53         if(c[i]==-1){
    54             if(!dfs(i)){
    55                 printf("0
    ");
    56                 return 0;
    57             }
    58         }
    59     int now=1;
    60     i=1;
    61     while(1){
    62         if(now>n)break;
    63         if(c[i]==0 && (tp1.empty() || tp1.top()>a[i])){
    64             tp1.push(a[i]);
    65             ans[++t]=1;
    66             i++;
    67             continue;
    68         }
    69         if(!tp1.empty() && tp1.top()==now){
    70             ans[++t]=2;
    71             tp1.pop();
    72             now++;
    73             continue;
    74         }
    75         if(c[i]==1 && (tp2.empty() || tp2.top()>a[i])){
    76             tp2.push(a[i]);
    77             ans[++t]=3;
    78             i++;
    79             continue;
    80         }
    81         if(!tp2.empty() && tp2.top()==now){
    82             tp2.pop();
    83             ans[++t]=4;
    84             now++;
    85             continue;
    86         }
    87     }
    88     for(i=1;i<=t;i++)printf("%c ",(char)ans[i]+'a'-1);
    89     printf("
    ");
    90     return 0;
    91 }
  • 相关阅读:
    104.Maximum Depth of Binary Tree
    103.Binary Tree Zigzag Level Order Traversal
    102.Binary Tree Level Order Traversal
    101.Symmetric Tree
    100.Same Tree
    99.Recover Binary Search Tree
    98.Validate Binary Search Tree
    97.Interleaving String
    static静态初始化块
    serialVersionUID作用
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6026975.html
Copyright © 2011-2022 走看看