ssoj1017集合栈(stack+set)

2 篇文章 0 订阅
1 篇文章 0 订阅
【题目】计算机的操作对象是一个以集合为元素的栈,一开始这个栈是空的。在每一步操作之后,栈顶集合中所含元素的个数是需要你输出的东西。计算机的操作指令有PUSH,DUP,UNION,INTERSECT,ADD。
•PUSH操作将一个空集合{}入栈
•DUP操作将把一个和栈顶元素相同的集合入栈
•UNION操作进行两次出栈操作,并且把出栈的两个集合的并入栈
•INTERSECT操作进行两次出栈操作,并且把出栈的两个集合的交入栈
•ADD操作进行两次出栈操作,并且把第一个出栈的集合作为一个元素,放入第二个出栈的集合中,然后把这个结果入栈
举一个例子,假设栈顶的元素是A={{},{{}}},而它下面的一个元素是B={{},{{{}}}}。
显然,集合A有2个元素,集合B也是。对于这个情况:
•UNION操作会产生集合{{},{{}},{{{}}}},这个集合有3个元素,所以要输出3
•INTERSECT操作会产生{{}},所以要输出1

ADD操作会产生{{},{{{}}},{{},{{}}}},所以要输出3

【思路】练习stl尤其是set的一个好题。

【代码】

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <set>
using namespace std;
const int maxn=2003;
const int mod=100000007;
std::set<int>st,st1,st2;
typedef set<int>::iterator it;
stack<set<int> >s;
int n,cnt=0;
char str[maxn];
int main(){
    scanf("%d",&n);
    while(n--){
	    scanf("%s",str);
	    if(str[0]=='P'){
			st.clear();
		    s.push(st);
		    printf("0\n");
		}
		else if(str[0]=='D'){
			st=s.top();
			s.push(st);
			printf("%d\n",st.size());
			st.clear();
		}
		else if(str[0]=='U'){
		    it i,j;
		    st1=s.top();s.pop();
		    st2=s.top();s.pop();
		    i=st1.begin();j=st2.begin();
		    while(i!=st1.end() && j!=st2.end()){
			    if(*i!=*j)st.insert(*i),st.insert(*j),++j,++i;
			    else st.insert(*i),++i,++j;
			}
			while(i!=st1.end())st.insert(*i),++i;
			while(j!=st2.end())st.insert(*j),++j;
			printf("%d\n",st.size());
			s.push(st);st.clear();
		}
		else if(str[0]=='I'){
			it i,j;
		    st1=s.top();s.pop();
		    st2=s.top();s.pop();
		    i=st1.begin();j=st2.begin();
		    while(i!=st1.end() && j!=st2.end()){
			    if(*i<*j)++i;
			    else if(*i>*j)++j;
			    else st.insert(*i),++i,++j;
			}
			printf("%d\n",st.size());
			s.push(st);st.clear();
		}
		else if(str[0]=='A'){
			int i=1;it iter;
		    st1=s.top();s.pop();
		    st=s.top();s.pop();
		    if(st1.size()==0)i=0;
		    else for(iter=st1.begin();iter!=st1.end();++iter)i=(i*maxn%mod+*iter+11)%mod;
		    if(st.find(i)==st.end())st.insert(i);
		    s.push(st);
		    printf("%d\n",st.size());
		    st.clear();
		}
	}
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值