如下是我對正確性的一些解釋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; }