题目:http://acm.hdu.edu.cn/showproblem.php?pid=5818
题意:
有两个栈A和B,有三种操作:
- push X v 向X栈中压入一个数v
- pop X 打印出X栈顶元素
- merge X1 X2 把X2中的元素按照加入的顺序合并到X1栈中
分析:
这题用优先队列去模拟即可,设置每个数的优先级,后加入的设置优先级高,就可以优先出队(栈)了。
官方题解:
比较简单巧妙的一个做法是引入一个新的栈C,每次合并的时候就把A和B合并到C上,然后把A和B都清空. push还是按正常做,pop注意当遇到要pop的栈为空时,因为题目保证不会对空栈进行pop操作,所以这时应直接改为对C栈进行pop操作. 这样做因为保证每个元素最多只在一次合并中被处理到,pop和push操作当然也是每个元素只做一次,所以总复杂度是O(N)的. 另一种做法是用链表来直接模拟,复杂度也是O(N),但代码量稍大一些.
struct item{
int val,id;
item(int val,int id):val(val),id(id){}
bool operator < (const item& rhs) const{
return id<rhs.id;
}
};
int main()
{
int n,cas=0,v;
char s[10];
while(~scanf("%d",&n)&&n){
printf("Case #%d:
",++cas);
priority_queue<item>q[2];
int t=0;
for(int i=1;i<=n;i++){
scanf("%s",s);
if(s[1]=='u'){
scanf("%s%d",s,&v);
if(s[0]=='A')q[t].push(item(v,i));
else q[t^1].push(item(v,i));
}
else if(s[1]=='o'){
scanf("%s",s);
if(s[0]=='A')v=q[t].top().val, q[t].pop();
else v=q[t^1].top().val, q[t^1].pop();
printf("%d
",v);
}
else{
scanf("%s",s);
if(s[0]=='A'){
if(q[t^1].size()>q[t].size())
t=t^1;
while(!q[t^1].empty())q[t].push(q[t^1].top()),q[t^1].pop();
}
else {
if(q[t^1].size()<q[t].size())
t=t^1;
while(!q[t].empty())q[t^1].push(q[t].top()),q[t].pop();
}
scanf("%s",s);
}
}
}
return 0;
}