UVA12096 集合栈计算机 The SetStack Computer

题意

对于一个以集合为元素的栈,初始时栈为空。 输入的命令有如下几种: PUSH:将空集{}压栈 DUP:将栈顶元素复制一份压入栈中 UNION:先进行两次弹栈,将获得的集合A和B取并集,将结果压栈 INTERSECTION:先进行两次弹栈,将获得的集合A和B取交集,将结果压栈 ADD:先进行两次弹栈,将获得的集合A和B中,先出栈的集合(如A先)加入到后出栈的集合,将结果压栈 输出每一步操作后栈顶集合的元素的个数。

输入样例

2
9
PUSH
DUP
ADD
PUSH
ADD
DUP
ADD
DUP
UNION
5
PUSH
PUSH
ADD
PUSH
INTERSECT

输出样例

0
0
1
0
1
1
2
2
2
***
0
0
1
0
0
***

参考代码

#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<stack>
#include<string>
#include<algorithm>
using namespace std;

typedef set<int> Set;//集合里面还是集合,但我们把它映射成了数字也就是里面存的都是数字。
map<Set, int> IDcollect;//把集合映射成数字(栈中的)
vector<Set> Setcollect;//用于给集合进行标号,也就是映射数字,对应Set的下标和集合映射。
stack<int> s;
int n,m;
string str;
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())

//查找指定集合x的ID
/*
在IDcollect中进行查找,未找到说明还没进行映射,则存入,并返回其下标。
如果找到则,直接返回其下标即可。
*/
int ID(Set x) {
	if (!IDcollect.count(x))
	 {//IDcollect中没有,存入Setcollect,如果有,则最后直接返回即可。
		Setcollect.push_back(x);
		IDcollect[x] = Setcollect.size() - 1;
	}
	return IDcollect[x];
}
int main() {
	cin >> n;
	while (n--) {
		cin >> m;
		for (int i = 0; i < m; i++) {
			cin >> str;
			if (str[0] == 'P') {
				s.push(ID(Set()));
			}
			else if (str[0] == 'D') {
				s.push(s.top());
			}
			else {
				Set s1 = Setcollect[s.top()];
				s.pop();
				Set s2 = Setcollect[s.top()];
				s.pop();
				Set x;
				if (str[0] == 'U') {
					set_union(ALL(s1), ALL(s2), INS(x));
				}
				else if(str[0]=='I'){
					set_intersection(ALL(s1), ALL(s2), INS(x));
				}
				else {
					x = s2;
					x.insert(ID(s1));
				}
				s.push(ID(x));
			}
			cout << Setcollect[s.top()].size() << endl;
		}
		cout << "***" << endl;
	}
	return 0;
}

版权声明:本文为LXYDSF原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。