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
輸出:a b a a b b a b
能彈出,則彈出,優先放在s1中(輸出的方案按照字典序輸出,所以優先放在s1中)
首先思考:
能放在s1中的情況:
1.s1棧頂為0,即s1沒有數
2.當前輸入值小於s1棧頂,而且s2棧頂沒有數
肯定不能放在s1的情況:
1. 當前輸入的值大於s1棧頂
特殊情況:當前輸入值小於s1、s2棧頂
例如:s1棧頂 = 10,s2棧頂= 8,現在進來乙個7,看上去很難判斷7到底放在**,如果放s1,後面來個9,再來個6,就無法放了。但是如果先來的是6,並且已經排完了1-5,那麼我們可以在後續操作中把7弄走仔細想想不難發現,7不能放在s1中,當且僅當存在乙個位置k,滿足a[k]>7,且在k之後有位置l,滿足a[l]<7也就是說(i, j, k)不能同時在棧中,當且僅當(i < j < k)且(a[k] < a[i] < a[j])
//a存放的是輸入序列
vector<
char
> v;
//定義乙個v的動態陣列
bool
check
(int pos)
intmain()
while
(now == s1[tp1]
|| now == s2[tp2])if
(i == n +1)
break
;//所有的數,都找完了跳出迴圈圈 if(
check
(i))
//放在s1裡面 if(
!tp2 || a[i]
< s2[tp2]
)//放在s2裡面
cout<<
0<
//上述情況都不符合,表示該數找不到存放位置,輸出
return0;
}if(tp1 || tp2)
//如果s1、s2中有數,表示沒有排序完,輸出0
for(
int i =
0; i < v.
size()
; i++
) cout<
<<
" ";
return0;
}
貪心演算法(1) 雙指標貪心演算法
leetcode例題 給定乙個字串 s 和乙個字元模式 p 實現乙個支援 和 的萬用字元匹配。可以匹配任何單個字元。可以匹配任意字串 包括空字串 兩個字串完全匹配才算匹配成功。說明 s 可能為空,且只包含從 a z 的小寫字母。p 可能為空,且只包含從 a z 的小寫字母,以及字元 和 示例 1 輸...
貪心演算法 拓撲排序
關於貪心演算法介紹 乙個複雜的工程,經常可以分解成一組簡單一些的任務,這些任務完成了,整個工程就完成了。例如汽車組裝問題可以分解成 底盤安裝 車軸安裝 車輪安裝 座位安裝 噴漆 剎車安裝 車門安裝等。但是這些任務之間有個先後順序,例如車軸安裝之前先要進行底盤安裝。類似的問題,可以將任務和人物的先後順...
NOIP2008 雙棧排序
link 考慮什麼時候 i,j i,j i,j 可以被放到同乙個棧裡面 我們只需要考慮如果我們把 i,j i,j i,j 放一起後面會不會出現矛盾 假設有 i j i j k,觀察每一種排列,只有當 a k a kak 的時候,是會出現問題的,我們不能構造一種方案滿足這個條件 所以我們通過計算字尾最...