考虑只有一个栈的话。对于三个数字
\[i<j<k,a_k<a_i<a_j \]那么进行栈排序的话,需要i比j先出栈,k比i,j先出栈,这就产生矛盾了。需要在增加一个栈来了。
显然i,j不能在同一个栈进行排序。所以要分开
我们对于这种情况,在i,j之间连边。跑二分图染色,染色失败则无解.
这题还要求输出字典序最小的操作,push操作的优先级更高,只到栈不合法的时候才pop,就是栈顶到栈底不再单调递增的时候就是非法,要pop。再向第二个栈push的时候,我们要判断第一个栈能不能pop,这样字典序更小.最后按顺序模拟出栈
const int N = 1e3 + 79;
int n, a[N], color[N];
std::stack<int>s[2];
int pos(1);
struct graph {
int head[N], tot = 1, next[N << 1], ver[N << 1];
inline void add(int a, int b) {
ver[++tot] = b;
next[tot] = head[a];
head[a] = tot;
}
} G;
int smin[N];
int q[N];
inline bool Pop(int id) {
if(s[id].size() && s[id].top() == pos) {
putchar(id ? 'd' : 'b');
s[id].pop();
putchar(' ');
++pos;
return true;
}
return false;
}
inline void Push(int x, int id) {
if(id == 1) {
while(Pop(0));
}
while(s[id].size() && s[id].top() < x) {
if(!Pop(id)) {
Pop(id ^ 1);
}
}
if(id == 1) {
while(Pop(0));
}
s[id].push(x);
putchar(id ? 'c' : 'a');
putchar(' ');
}
int main() {
read(n);
rep(i, 1, n) {
read(a[i]);
}
smin[n + 1] = n + 1;
drp(i, n, 1) {
smin[i] = min(smin[i + 1], a[i]);
}
memset(color, 0xff, sizeof color);
rep(i, 1, n) {
rep(j, i + 1, n) {
if(smin[j + 1] < a[i] && a[i] < a[j]) {
G.add(i, j);
G.add(j, i);
}
}
}
rep(i, 1, n) {
if(!~color[i]) {
q[q[0] = 1] = i;
color[i] = 0;
rep(kkk, 1, q[0]) {
int x = q[kkk];
repg(x) {
int y(G.ver[i]);
if(~color[y] && color[y] != (color[x] ^ 1)) {
puts("0");
return 0;
}
if(!~color[y]) {
q[++q[0]] = y;
color[y] = color[x] ^ 1;
}
}
}
}
}
rep(i, 1, n) {
Push(a[i], color[i]);
}
while(s[0].size() || s[1].size()) {
Pop(0);
Pop(1);
}
return 0;
}