想法模拟题——Stack

题目链接 点击打开链接

给你两个栈,push操作是压入,pop是弹出栈顶并输出,merge是将后面的栈合并到前面的栈,并且按压入时间排序。

 

Solution1 前两个仅仅需要模拟就行了,主要是解决merge,倒过来倒过去,很容易超时,可以定义nowA所属的栈,!nowB所属的栈,那么将元素少的栈合并到元素多的栈里,如果merge A B的时候B的元素多,那么我们把A中的倒入B中,now取反即可。用结构体保存时间。

Solution2 比较简单巧妙的一个做法是引入一个新的栈C,每次合并的时候就把AB合并到C上,然后把AB都清空. push还是按正常做,pop注意当遇到要pop的栈为空时,因为题目保证不会对空栈进行pop操作,所以这时应直接改为对C栈进行pop操作. 这样做因为保证每个元素最多只在一次合并中被处理到,poppush操作当然也是每个元素只做一次,所以总复杂度是O(N). 另一种做法是用链表来直接模拟,复杂度也是O(N),但代码量稍大一些.

这里只给出1的代码


#include<stdio.h>
#include<set>
using namespace std;

int nu[100009];

int main(){
	int n;int t=1;
	while(scanf("%d",&n),n){

		printf("Case #%d:\n",t++);
		int tim=0;
		int now=0;
		set<int>s[2];
		set<int>::iterator it;

		char str[7];
		while(n--){
			scanf("%s",str);
			if(str[1]=='u'){
				scanf("%s",str);
				int temp;
				scanf("%d",&temp);

				nu[++tim]=temp;
				if(str[0]=='A') s[now].insert(tim);
				else            s[!now].insert(tim);
			}
			else if(str[0]=='p'){
				scanf("%s",str);
				int temp;
				if(str[0]=='A')temp=now;
				else temp=!now;
				
				it=s[temp].end();it--;
				printf("%d\n",nu[*it]);s[temp].erase(it);
			}
			else{
				scanf("%s",str);
				scanf("%s",str);
				
				if(str[0]=='B'){
					if(s[!now].size() < s[now].size()){
						it = s[!now].begin();
						while(it != s[!now].end()){
							s[now].insert(*it);it ++;
						}s[!now].clear();
					}
					else{
						it = s[now].begin();
						while(it != s[now].end()){
							s[!now].insert(*it);it ++;
						}s[now].clear();
						now=!now;
					}
				}
				else{
					if(s[now].size()<s[!now].size()){
						it = s[now].begin();
						while(it!=s[now].end()){
							s[!now].insert(*it);it++;
						}s[now].clear();
					}
					else{
						it = s[!now].begin();
						while(it!=s[!now].end()){
							s[now].insert(*it);it++;
						}s[!now].clear();
						now=!now;
					}
				}
			}
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值