​http://www.elijahqi.win/archives/1145​​​
题目描述

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)排序的操作序列:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define inf 0x7f7f7f7f
#define N 1100
using namespace std;
inline char gc(){
static char now[1<<16], *S, *T;
if(S==T){T=(S=now)+fread(now, 1, 1<<16, stdin); if(S==T)return EOF;}
return *S++;
}
inline int read(){
int x=0;char ch=gc();
while (ch<'0'||ch>'9') ch=gc();
while (ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=gc();}
return x;
}
int color[N];int h[N],s1[N],s2[N],a[N],min1[N],num,n;
struct node{
int y,next;
}data[N*N*2];
inline void insert1(int x,int y){
data[++num].y=y;data[num].next=h[x];h[x]=num;
data[++num].y=x;data[num].next=h[y];h[y]=num;
}
bool dfs(int x,int colour){
color[x]=colour;
for (int i=h[x];i;i=data[i].next){
int y=data[i].y;if (color[y]==color[x]) return false;
if (color[y]!=-1) continue;if (!dfs(y,colour^1)) return false;
}
return true;
}
int main(){
freopen("1155.in","r",stdin);
n=read();
for (int i=1;i<=n;++i) a[i]=read();min1[n+1]=inf;
for (int i=n;i>=1;--i) min1[i]=min(a[i],min1[i+1]);
for (int i=1;i<=n;++i)
for (int j=i+1;j<=n;++j)
if (a[i]<a[j]&&min1[j+1]<a[i]) insert1(i,j);
memset(color,-1,sizeof(color));
for (int i=1;i<=n;++i) if (color[i]==-1) if (!dfs(i,0)){printf("0");return 0;}
int top1=0,top2=0,now=1;
for (int i=1;i<=n;++i){
if (!color[i]){printf("a ");s1[++top1]=a[i];
}else{printf("c ");s2[++top2]=a[i];}
while (s1[top1]==now||s2[top2]==now){
if (s1[top1]==now){
printf("b ");top1--;
}
if (s2[top2]==now){
printf("d ");top2--;
}++now;
}
}
return 0;
}