1. 程式人生 > >HDU5818之優先佇列

HDU5818之優先佇列

題意:有兩個棧,有3種操作。 第一種是往其中一個棧加入一個數; 第二種是取出其中一個棧的頂端數字; 第三種是將其中一個棧的所有元素放入另外一個棧,元素順序依舊按照加入順序來放。

然後官方題解是這樣的: 比較簡單巧妙的一個做法是引入一個新的棧C,每次合併的時候就把A和B合併到C上,然後把A和B都清空. push還是按正常做,pop注意當遇到要pop的棧為空時,因為題目保證不會對空棧進行pop操作,所以這時應直接改為對C棧進行pop操作. 這樣做因為保證每個元素最多隻在一次合併中被處理到,pop和push操作當然也是每個元素只做一次,所以總複雜度是O(N)的. 另一種做法是用連結串列來直接模擬,複雜度也是O(N),但程式碼量稍大一些.

其實這題用三個優先佇列做就好了。。

七夕打比賽果然是有毒的QAQ。

詳情見程式碼:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef pair <int , int > pi;
priority_queue<pi>a;
priority_queue<pi>b;
priority_queue<pi>c;
int
cnt; void init() { while(!a.empty()) { a.pop(); } while(!b.empty()) { b.pop(); } while(!c.empty()) { c.pop(); } cnt=0; } void workpush(char aim) { if(aim=='A') { int n; scanf("%d",&n); a.push(make_pair(cnt++,n)); } else
{ int n; scanf("%d",&n); b.push(make_pair(cnt++,n)); } } void workpop(char aim)//這裡,如果沒有merge過,就可以直接從原棧中取值。 //如果merge過了,就從混合後的佇列中取值。 { if(aim=='A') { if(!a.empty()) { pi x=a.top(); a.pop(); printf("%d\n",x.second); } else { pi x=c.top(); c.pop(); printf("%d\n",x.second); } return ; } if(aim=='B') { if(!b.empty()) { pi x=b.top(); b.pop(); printf("%d\n",x.second); } else { pi x=c.top(); c.pop(); printf("%d\n",x.second); } return ; } return ; } void workmer(char aim)//不管是誰往誰裡面加,都全部放入一個佇列中。 { char ch; scanf(" %c",&ch); while(!a.empty()) { pi x=a.top(); c.push(x); a.pop(); } while(!b.empty()) { pi x=b.top(); c.push(x); b.pop(); } } int main (void) { int num; int cas=1; while(~scanf("%d",&num)) { if(num==0) break; init(); char ch[10]; char aim; printf("Case #%d:\n",cas++); while(num--) { scanf("%s %c",ch,&aim); if(ch[1]=='u') { workpush(aim); } if(ch[1]=='o') { workpop(aim); } if(ch[0]=='m') { workmer(aim); } } } return 0; }