NOIP 雙棧排序(貪心演算法)

2021-10-03 06:16:57 字數 2194 閱讀 3210

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 的時候,是會出現問題的,我們不能構造一種方案滿足這個條件 所以我們通過計算字尾最...