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>
Input
输入有多组Case,每个Case第一行是一个整数n(n<=1000)。
第二行有n个用空格隔开的正整数,构成一个1~n的排列。
Output
每组Case输出一行,如果输入的排列不是“可双栈排序排列”,输出数字0;否则输出字典序最小的操作序列,每两个操作之间用空格隔开,行尾没有空格。
Sample Input
4 1 3 2 4 4 2 3 4 1
Sample Output
a b a a b b a b 0
算是第一次数据结构soj题最难的一道了,想了好久还是上网看题解了,说实话题解也看了很久才模仿着写了出来= =
详解太多了,不过首先得知道二分图染色是个什么东西,巧了这东西暑假无聊正好做过,就是简单的图dfs
放个AC的代码先:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <stack>
#include <climits>
using namespace std;
const int MAX_N=1002;
bool edge[MAX_N][MAX_N],res=true;
int s[MAX_N],minS[MAX_N],color[MAX_N];
int n;
void dfs(int pos,int c)
{
color[pos]=c;
for(int i=0;i<n;i++)
{
if(edge[pos][i])
{
if(color[i]==c)
{
res=false;
return;
}
if(!color[i])
dfs(i,3-c);
}
}
}
int main()
{
while(cin>>n)
{
stack<int> sa,sb;
memset(s,0,sizeof(s));
memset(minS,0,sizeof(minS));
memset(color,0,sizeof(color));
memset(edge,0,sizeof(edge));
res=true;
for(int i=0;i<n;i++)
cin>>s[i];
minS[n]=INT_MAX;
for(int i=n-1;i>=0;i--)
minS[i]=min(minS[i+1],s[i]);
for(int i=0;i<n-1;i++)
for(int j=i+1;j<n;j++)
if(s[i]<s[j]&&minS[j+1]<s[i])
edge[i][j]=edge[j][i]=true;
for(int i=0;i<n;i++)
if(!color[i])
dfs(i,1);
if(!res)
{
cout<<"0"<<endl;
continue;
}
int curOut=1;
string output;
for(int i=0;i<n;i++)
{
if(color[i]==1)
{
sa.push(s[i]);
output+="a";
}
else
{
sb.push(s[i]);
output+="c";
}
while((!sa.empty()&&sa.top()==curOut)||(!sb.empty()&&sb.top()==curOut))
{
if(!sa.empty()&&sa.top()==curOut)
{
output+="b";
sa.pop();
}
else
{
output+="d";
sb.pop();
}
curOut++;
}
}
for(int i=0;i<output.size();i++)
printf(i==0?"%c":" %c",output[i]);
cout<<endl;
}
return 0;
}
详解就看这位师兄的吧https://blog.csdn.net/u014207839/article/details/40460339
代码是参考https://blog.csdn.net/kqzxcmh/article/details/9566813的,改了一些竞赛选手的通病可能我的好看一点点= =