菜雞還沒學二分圖。。。
題意:
給定乙個序列,問能否雙棧排序,如果能,請輸出字典序最小的方案;
操作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...