title: given N and a string of numbers, this string of numbers is a 1~n arrangement. Now you want to sort these numbers with two stacks. First of all, to determine whether there is a solution, and then output the smallest dictionary order scheme:
into the stack 1, output A, stack 1, output b
Into the stack 2, output C, out of the stack 2, output D
Analysis:
First of all, we must first consider whether there is a solution. For the case of no solution, it must be when a certain number of x0, stack 1, stack 2 The first element can not be ejected, and x0 than the stack 1, 2 team first elements are larger, then can not be sorted.
So consider when a and B cannot be in the same stack:
When and only if, a<b, and exists C, makes a>c. and satisfies a position at B front, b position in front of c. That is, because of the existence of C, a can not pop off, but B put in, a will never pop.
This will allow you to find all the numbers that cannot be in the same stack as the x0.
When judging the non-solution, it is possible to connect all of the above A and B without an edge, either with a binary graph or with an offset and a check set.
Output, because the dictionary order is the smallest, so the first element must be put in the stack 1, so that can be preprocessed out all the number to enter which stack. Can be into the stack 1 of all into the stack 1.
Then the simulation implementation, each time to determine whether you can pop off the top of the stack elements, and then according to the previous preprocessing scheme put in the number.
#include <bits/stdc++.h>using namespacestd;Const intn=1010;intA[n],la[n],co[n];intN;intHead[n];intCnt=1;BOOLflag=0;intsta[3][n];//record stack 1, stack 2inttop[3];//Record Stack TopintGo[n];//The number in this position to go to which stackinthas;//What 's the date of the stack?structnode{intTO,NXT;} bian[2*N];voidAddintXinty) {bian[++cnt].nxt=Head[x]; Bian[cnt].to=y; HEAD[X]=CNT;}//Build EdgevoidDFS1 (intXintFaintSe//1 Black 2 White{ if(flag)return; CO[X]=se; for(intI=head[x];i;i=bian[i].nxt) { inty=bian[i].to; if(Y==FA)Continue; if(Co[y]) {if(co[y]==Co[x]) {Flag=1;return; } } Else{DFS1 (y,x,3-SE); } }}//The judging of the staining of the binary graphvoidDFS2 (intXintse) {Go[x]=se; for(intI=head[x];i;i=bian[i].nxt) { inty=bian[i].to; if(!Go[y]) {dfs2 (Y,3-SE); } }}//pre-processing the stack of the go (in fact, can also be processed in the binary graph dyeing, this step is saved)voidCheckintNow ) { BOOLf=0; while(top[now]&&has+1==Sta[now][top[now]]) {f=1; printf ("%c", now==1?'b':'D'); has++; Top[now]--; } if(f)//A successful pop will find anotherCheck3-Now );}//Check if pop is possibleintMain () {scanf ("%d",&N); for(intI=1; i<=n;i++) scanf ("%d",&A[i]); for(intI=1; i<=n;i++) for(intj=n;j>=i+1; j--) { if(a[i]>A[j]) {La[i]=j; Break;} }//find the position of a C on the last side of a. for(intI=1; i<=n;i++) for(intj=i+1; j<=la[i];j++) { if(a[i]<A[j]) {Add (I,J); Add (j,i); } }//between A and C, all B is going to build a side with a. for(intI=1; i<=n;i++) { if(flag==1) Break; if(!co[i]) DFS1 (i,0,1); } if(flag) {printf ("0"); return 0; }//Judginggo[1]=1; for(intx=1; x<=n;x++) { if(!go[x]) go[x]=1, DFS2 (x,1); } for(intI=1; i<=n;i++) {Check (1); Check (2); sta[go[i]][++top[go[i]]]=A[i]; printf ("%c", go[i]==1?'a':'C'); } Check (1); Check (2);//Finally, you have to judge, the output is finished. return 0;}
NOIP 2008 Double Stack Sequencing