我们可以考虑在什么情况下会需要双栈;
middle big small ;
这样的情况需要双栈;
因为我们 middle 入栈后;
不能直接弹出;
而是需要等待 small 进入;
所以这时候需要把 big 压入另一个栈中;
所以我们找这样的三个点;
将 middle and big 连边;
然后染色;
如果有相邻的两个点的颜色一样;
证明不合法;
否则,模拟;
#include "iostream"
#include "stdio.h"
#include "algorithm"
#define II int
#define C char
#define R register
#define I 123456
using namespace std;
struct node {
II to,up;
} aa[I];
C k[3], p[3];
II head[I], stack[2][I], _top[3], a[I], wei[I], inq[I], in[I], back[I];
II _tot,n;
II smaller(R II x,R II y) { return x>y ? y : x ; }
void add(R II x,R II y)
{
aa[++_tot].to=y;
aa[_tot].up=head[x];
head[x]=_tot;
}
void dfs(R II x,R II o)
{
inq[x]=1;
in[x]=o;
for(R II i=head[x];i;i=aa[i].up)
{
R II go=aa[i].to;
if(!inq[go]) {
dfs(go,o^1);
} else if(in[go]==in[x]) {
printf("0\n");
exit(0);
}
}
}
int main()
{
scanf("%d",&n);
for(R II i=1;i<=n;i++)
{
scanf("%d",&a[i]);
wei[a[i]]=i;
}
back[n]=a[n];
for(R II i=n-1;i;i--) back[i]=smaller(back[i+1],a[i]);
for(R II i=1;i<n;i++)
{
for(R II j=i+1;j<n;j++)
{
if(back[j+1]<a[i] && a[j]>a[i]) {
add(i,j);
add(j,i);
}
}
}
for(R II i=1;i<=n;i++)
{
if(!inq[i]) {
dfs(i,0);
}
}
R II bit=1;
if(in[1]) {
k[1]='a'; k[0]='c';
p[1]='b'; p[0]='d';
} else {
k[0]='a'; k[1]='c';
p[0]='b'; p[1]='d';
}
for(R II i=1;i<=n;i++)
{
stack[in[i]][++_top[in[i]]]=a[i];
printf("%c ",k[in[i]]);
while (stack[0][_top[0]]==bit || stack[1][_top[1]]==bit) {
printf("%c ",p[in[wei[bit]]]);
_top[in[wei[bit]]]--;
bit++;
}
}
exit(0);
}