如下是我对正确性的一些解释c++
因为元素按顺序进栈,因此咱们要保证在前面的字典序尽量小,因此优先让先进栈的进栈1,进不了栈1才进栈2,故两个栈中的元素是惟一肯定的spa
可是b,c的相对顺序和a,d的相对顺序是不肯定的code
b,c对应出栈1,入栈2,因为咱们在代码中能出栈就出栈,因此字典序是正确的blog
a,d对应入栈1,出栈2,因为咱们在代码中能出栈就出栈,因此会输出d,a,而实际上a,d是更优的排序
因此咱们只须要在不改变上述肯定的相对顺序的前提下交换d,a便可,即交换全部相邻的d,aip
#include<bits/stdc++.h> using namespace std; #define go(i,a,b) for(int i=a;i<=b;++i) #define com(i,a,b) for(int i=a;i>=b;--i) #define mem(a,b) memset(a,b,sizeof(a)) #define fo(i,a) for(int i=0;i<a;++i) #define il inline const int inf=0x3f3f3f3f,N=1010; int n,a[N],suf[N],co[N],tot; bool g[N][N]; char ans[N*2]; bool dfs(int u,int c){ co[u]=c; go(i,1,n){ if(!g[u][i]) continue; if(co[i]==c) return 0; if(!co[i]&&!dfs(i,3-c)) return 0; } return 1; } void solve(){ stack<int>s1,s2; int now=1; go(i,1,n){ if(co[i]==1){ s1.push(a[i]); ans[++tot]='a'; } else{ s2.push(a[i]); ans[++tot]='c'; } while(1){ if(!s1.empty()&&s1.top()==now) s1.pop(),ans[++tot]='b',++now; else if(!s2.empty()&&s2.top()==now) s2.pop(),ans[++tot]='d',++now; else break; } } go(i,1,tot) if(ans[i]=='a'&&ans[i-1]=='d') swap(ans[i],ans[i-1]); } int main(){ //freopen("input.txt","r",stdin); cin>>n; go(i,1,n) scanf("%d",a+i); suf[n+1]=inf; com(i,n,1) suf[i]=min(suf[i+1],a[i]); go(i,1,n) go(j,i+1,n){ if(a[i]<a[j]&&suf[j+1]<a[i]) g[i][j]=g[j][i]=1; } go(i,1,n){ if(!co[i]&&!dfs(i,1)){ puts("0"); return 0; } } solve(); go(i,1,tot) printf("%c ",ans[i]); return 0; }