HDU5818之優先佇列
阿新 • • 發佈:2018-12-24
題意:有兩個棧,有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;
}