牛客 雙棧排序 niop

2021-10-23 10:43:48 字數 2837 閱讀 3522

菜雞還沒學二分圖。。。

題意:

給定乙個序列,問能否雙棧排序,如果能,請輸出字典序最小的方案;

操作a:如果輸入序列不為空,將第乙個元素壓入棧s1

操作b:如果棧s1不為空,將s1棧頂元素彈出至輸出序列

操作c:如果輸入序列不為空,將第乙個元素壓入棧s2

操作d:如果棧s2不為空,將s2棧頂元素彈出至輸出序列

題解:

題目讓以字典序最小的順序輸出,那麼這樣的話我們操作順序直接以abcd來操作即可。

對於乙個數,我們應該把他放進棧a呢,還是放進棧b呢。

因為字典序最小,所以我們如果能放進棧a實現這些操作,那麼我們必然不會把他放進棧b實現這個操作。

我們先考慮乙個棧的情況。

如果序列是 3 1 4 2 5

不難看出,這個如果只有乙個棧的情況下,這個是無法完成題目要求的。分析一下。

3(3入棧)

3 1 (1入棧)

3 (1出棧)

3 4 (4入棧) ???

彷彿出了點問題,3還沒出來呢,4怎麼能進去呢。。但是4不進去,2也進不去啊,(彷彿出現了混亂

從這裡可以發現乙個規律

棧頂元素一定要小於棧內元素,若當前最小值還未入棧, 那麼這個棧一定不能彈, 只能一直加, 直到最小值入棧, 那麼在這個過程中, 就有可能出現衝突。

但是這裡用的是兩個棧,如果這個a棧不能放,我們可以先把元素放到b棧過度一下。

對於兩個棧來講,如果能放進a棧的話,我們就不要把他放進b棧,所以放a棧的時候我們需要特判一下,這個元素到底能不能放進a棧,如果放進去後面會不會產生衝突。

首先我們要滿足一點,就是棧頂元素要小於棧內元素

(la.

empty()

||la.

top(

)>a[cnt]

)

第二點我們要檢查一下之後的序列會不會導致 把元素放進a棧後誤解,如果是這樣,我們嘗試放入b棧

也就是這個check函式,如果棧b為空,那麼我們可以用b棧作為乙個輔助棧,肯定可以。

然後我麼做只有乙個棧的時候的檢查,也就是若當前最小值還未入棧, 那麼這個棧一定不能彈, 只能一直加, 直到最小值入棧, 那麼在這個過程中, 就有可能出現衝突。但是在這個條件下,不要忘記還有b棧可以輔助,如果後面元素大於棧頂,但是小於b棧的頂元素,那麼我們可以暫時放到b棧中,兩者可以交替用。

如果都大於的話,那麼我們就要考慮從這個位置之後的數,有沒有小於當前位置的,如果小於,只能返回false了,因為b棧也被用過了,這裡聯想一下乙個棧的情況,這兩個棧後面不能有比 當前棧頂元素都小的元素了,如果出現,就會發生上面所說的混亂,也就是前面標黑的那一段話。

為什麼要從break後面的位置來找有沒有比當前棧頂小的數,因為如果數都比棧頂大的話,棧頂元素就會在到達那個最大元素的位置時被丟擲,所以沒有影響!! 如果那個位置之後有小於棧頂的數,那就產生衝突了

(不如拿筆嘗試一下這組資料)10 2 8 1 7 9 3 4 5 6

bool

check

(int pos)

**:

/*keep on going never give up*/

#pragma gcc optimize(3,"ofast","inline")

#include

#define endl '\n'

#define ios std::ios::sync_with_stdio(false),cin.tie(0), cout.tie(0);

//#define int long long

const

int maxn =

1e4+10;

const

int maxn =

0x3f3f3f3f

;const

int minn =

0xc0c0c00c

;typedef

long

long ll;

const

int mod =

1e9+7;

using

namespace std;

int a[maxn]

;vector<

int> ans;

vector<

char

> now;

stack<

int> la,lb;

int n;

bool

check

(int pos)

intmain()

elseif(

!la.

empty()

&&ans.

back()

+1==la.

top())

elseif(

(lb.

empty()

||lb.

top(

)>a[cnt]

)&&cnt<=n)

elseif(

!lb.

empty()

&&ans.

back()

+1==lb.

top())

if(!flag)

break

;//cout!flag) cout<<

0

for(

auto it : now) cout<" ";

return0;

}

大牛就是牛 雙棧排序

題目描述 tom最近在研究乙個有趣的排序問題。如圖所示,通過2個棧s1和s2,tom希望借助以下4種操作實現將輸入序列公升序排序。操作a 如果輸入序列不為空,將第乙個元素壓入棧s1 操作b 如果棧s1不為空,將s1棧頂元素彈出至輸出序列 操作c 如果輸入序列不為空,將第乙個元素壓入棧s2 操作d 如...

牛客網 14893 棧和排序

題目描述 給你乙個1 n的排列和乙個棧,入棧順序給定 你要在不打亂入棧順序的情況下,對陣列進行從大到小排序 當無法完全排序時,請輸出字典序最大的出棧序列 輸入描述 第一行乙個數n 第二行n個數,表示入棧的順序,用空格隔開,結尾無空格 輸出描述 輸出一行n個數表示答案,用空格隔開,結尾無空格 輸入 5...

牛客 雙端佇列

有 個整數需要排序,能用的工具是若干個雙端佇列。需要依次處理這n個數,可以 考慮排完後的序列,它是由若干雙端佇列組成。發現 對於每個雙端佇列,每個元素換成它在原有序列中的位置,一定是乙個先單調減後單調增的序列。但要討論相同的情況 發現 存在一種最優解,滿足相同的元素在同乙個雙端佇列中 include...