題目描述
Tom最近在研究一個有趣的排序問題。如圖所示,通過2個棧S1和S2,Tom希望借助以下4種操作實現將輸入序列升序排序。
操作a
如果輸入序列不為空,將第一個元素壓入棧S1
操作b
如果棧S1不為空,將S1棧頂元素彈出至輸出序列
操作c
如果輸入序列不為空,將第一個元素壓入棧S2
操作d
如果棧S2不為空,將S2棧頂元素彈出至輸出序列
如果一個1~n的排列P可以通過一系列操作使得輸出序列為1,2,…,(n-1),n,Tom就稱P是一個“可雙棧排序排列”。例如(1,3,2,4)就是一個“可雙棧排序序列”,而(2,3,4,1)不是。下圖描述了一個將(1,3,2,4)排序的操作序列:
當然,這樣的操作序列有可能有幾個,對于上例(1,3,2,4),是另外一個可行的操作序列。Tom希望知道其中字典序最小的操作序列是什么。
輸入輸出格式
輸入格式:
輸入文件twostack.in的第一行是一個整數n。
第二行有n個用空格隔開的正整數,構成一個1~n的排列。
輸出格式:
輸出文件twostack.out共一行,如果輸入的排列不是“可雙棧排序排列”,輸出數字0;否則輸出字典序最小的操作序列,每兩個操作之間用空格隔開,行尾沒有空格。
輸入輸出樣例
輸入樣例#1:
4
1 3 2 4
輸出樣例#1:
a b a a b b a b
輸入樣例#2:
4
2 3 4 1
輸出樣例#2:
0
輸入樣例#3:
3
2 3 1
輸出樣例#3:
a c a b b d
說明
30%的數據滿足: n<=10
50%的數據滿足: n<=50
100%的數據滿足: n<=1000
二分圖染色。
雙棧排序,明顯要把數分成獨立的兩半,也就是二分圖。
這里涉及到的二分圖操作就是判斷,然后模擬棧就好了。
如何實現?
minn[i]存儲(i+1)到n的最小值。
枚舉i,j,找到i<j且a[i]<a[j](i比j先進先出)。
如果minn[j+1]<a[i],就說明j后面還有比i小的數,i和j就不能再同一個棧里(j會擋著i),就在i,j間連邊。
最后染色判斷是否是二分圖,不是就0退;是的話都分在兩個棧里了,模擬出棧就好了。
哦對了,盡量扔到s1里。
//%%dxcdalao.
另附一篇驚天大模擬:paste.ubuntu.com/25835281/