pat_棧(二分+棧模擬)
阿新 • • 發佈:2020-09-12
現在,你需要實現一個棧,該棧要具有一個額外的操作:PeekMedian-返回棧中所有元素的中值。
對於 N 個元素,如果 N 為偶數,則中值定義從小到大第 N2 個元素;如果 N 為奇數,則中值定義為從小到大第 N+12 個元素。
輸入格式
第一行包含整數 N,表示命令數。
接下來 N 行,每行包含以下三種命令中的一種:
Push key
Pop
PeekMedian
其中 key 是一個不超過 105 的正整數。
輸出格式
對於每個 Push 操作,在頂部插入一個 key 值,不輸出任何內容。
對於每個 Pop 或 PeekMedian 命令,在一行中輸出相應的返回值。
如果命令無效,則輸出 Invalid。
資料範圍
1≤N≤105
方法一:2*multiset+stack模擬
這題有毒,用cin不能做,
#include<bits/stdc++.h> using namespace std; int mid; multiset<int> s1, s2; string s; void update() { multiset<int>:: iterator it; if (s1.size()<s2.size()) { it=s2.begin(); s1.insert(*it), s2.erase(it); }if (s1.size()>s2.size()+1) { it=s1.end(); it--; s2.insert(*it), s1.erase(it); }if (!s1.empty()) { it=s1.end(); it--; mid=*it; } } int main() { int n; scanf("%d",&n); stack<int> st; for (int i=0; i<n; i++) { cin>>s; if (s=="Pop") { if (st.empty()) cout << "Invalid" << '\n'; else { int t=st.top(); st.pop(); printf("%d\n", t); if (t>mid) s2.erase(s2.find(t)); else s1.erase(s1.find(t)); update(); } } else if (s=="Push") { getchar(); int e; scanf("%d",&e); st.push(e); if (s1.empty()||e<=mid) s1.insert(e); else s2.insert(e); update(); } else { if (st.empty()) printf("Invalid\n"); else printf("%d\n",mid); } } return 0; }
複雜度分析
- Time:\(O(nlogn)\),
- Space:\(O(n)\),