集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096)
程序员文章站
2022-12-15 08:03:35
集合栈计算机(The SetStack Computer, ACM/ICPC NWERC 2006,Uva12096) 题目描述 有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且支持以下操作: PUSH:空集“{}”入栈 DUP:把当前栈顶元素复制一份后再入栈 UNIO ......
集合栈计算机(the setstack computer, acm/icpc nwerc 2006,uva12096)
题目描述
有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且支持以下操作:
push:空集“{}”入栈
dup:把当前栈顶元素复制一份后再入栈
union:出栈两个集合,然后把两者的并集入栈
intersect:出栈两个集合,然后把二者的交集入栈
add:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈
每次操作后,输出栈顶集合的大小(即元素个数)。例如栈顶元素是a={ {}, {{}} }, 下一个元素是b={ {}, {{{}}} },则:
union操作将得到{ {}, {{}}, {{{}}} },输出3.
intersect操作将得到{ {} },输出1
add操作将得到{ {}, {{{}}}, { {}, {{}} } },输出3.
样例输入
6
push
push
union
push
push
add
样例输出
0
0
0
0
0
1
代码实现
#define local #include<set> #include<stack> #include<iostream> #include<map> #include<vector> #include<algorithm> // for set_union set_intersection using namespace std; /* push:空集{}入栈 union:出栈两个集合,然后把两者的并集入栈 intersect:出栈两个集合,然后把二者的交集入栈 add:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈。 */ typedef set<int> set; map<set,int> idcache; //set - id such as:idcache[set] vector<set> setcache; //id - cache such as:setcache[id] stack<int> s; int id(set x){ //光一个map数据结构还不够,这是因为有可能一个set还没有对应的id,所以这个函数应该包括的功能有:1.创建id(如果没有) 2.返回id if(!idcache.count(x)){ setcache.push_back(x); idcache[x]=setcache.size()-1;//!!!骚操作 } return idcache[x]; } int n; int main(){ #ifdef local freopen("data.in","r",stdin); freopen("data.out","w",stdout); #endif cin>>n; while(n--){ string exec; cin>>exec; if(exec[0] == 'p') s.push(id(set())); else if(exec[0] == 'd') s.push(s.top()); else{ set x1 = setcache[s.top()]; s.pop(); set x2 = setcache[s.top()]; s.pop(); set x; if(exec[0] == 'u') set_union(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(x,x.begin()));//!!!inserter if(exec[0] == 'i') set_intersection(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(x,x.begin()));//!!!inserter if(exec[0] == 'a'){ x=x2; x.insert(id(x1)); } s.push(id(x)); } cout<<setcache[s.top()].size()<<endl; } }
下一篇: 想做鸭子的土豆,不甘心只做土豆!