Codeforces Round #420 (Div. 2) - C
题目链接:http://codeforces.com/contest/821/problem/C
题意:起初有一个栈,给定2*n个命令,其中n个命令是往栈加入元素,另外n个命令是从栈中取出元素。你可以在任何操作之前重新排列目前栈内的元素,现在要求对于取出的元素序列为1~n。问你至少要重新排列栈内的元素几次。 题目保证出栈时下一个要求出栈的元素一定在栈内。
思路:
维护一个栈和优先队列
对于出栈操作,存在3中情况:
1,栈顶元素刚好是下一个要出栈的元素,直接出栈即可。
2,栈为空,队列头一定是下一个要出栈的元素,直接对头出队即可。
3,栈不为空,栈顶非下一个要出栈的元素,并且队头也非下一个要出栈的元素,将栈内元素全部加入队列中,清空栈,并且重排(由于优先队列就是一个堆,直接加入即可满足重排)。 重排后队头一定是下一个要出栈的元素。
由于题目保证出栈时下一个要求出栈的元素一定在栈内。所以只有上面3中情况。
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<queue> #include<vector> #include<time.h> #include<stack> #include<cmath> using namespace std; typedef long long int LL; const LL INF = 9223372036854775807; const int MAXN = 3e5 + 24; stack<int>st; priority_queue<int>buff; int main(){ //#ifdef kirito // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); //#endif // int start = clock(); int n; while (~scanf("%d", &n)){ int nextNum = 1, ans = 0; while (!st.empty()){ st.pop(); } while (!buff.empty()){ buff.pop(); } for (int i = 0; i < n * 2; i++){ char tpe[10]; int val; scanf("%s", tpe); if (tpe[0] == 'a'){ scanf("%d", &val); st.push(val); } else{ if (st.empty()){ buff.pop(); } else if (!st.empty() && st.top() == nextNum){ st.pop(); } else{ ans++; while (!st.empty()){ buff.push(st.top()); st.pop(); } buff.pop(); } nextNum++; } } printf("%d\n", ans); } //#ifdef LOCAL_TIME // cout << "[Finished in " << clock() - start << " ms]" << endl; //#endif return 0; }