题意
输入
输出
样例输入
样例输出
有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个开始为空的栈并且支持以下操作。 1.PUSH:空集“{}”入栈。 2.DUP:把当前栈顶元素复制一份后在入栈。 3.UNION:出栈两个集合,然后把二者的并集入栈。 4.INTERSECT:出栈两个集合,然后把二者的交集入栈。 5.ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈。 例如,栈顶元素是A = { {},{{}} },下一个元素是B = { {}, {{{}}} },则: UNION 操作将得到{ {}, {{}}, {{{}}} },输出3. INTERSECT 操作将得到{ {} },输出1。 ADD 操作将得到{ {}, {{{}}},{{} , {{}}} },输出3。
第一行有一个整数T(0<=T<=5)表示有T组测试数据。 每组测试数据有N(0<=N<=2000)次操作,保证操作均能顺利进行(不需要对空栈执行出栈操作)。
对于输入中指定的每个操作,输出栈顶集合的大小(即元素个数)并换行。 每组测试数据后输出一行“***”。
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 ***
不得不说再一次见识到了STL容器的强大,竟然还有这种函数,这次真正的跪下来膜拜了,唉,以后估计用不多,就记在小本本上了,感谢刘汝佳,感谢紫书!
#include <set> #include <map> #include <stack> #include <vector> #include <string> #include <iostream> #include <algorithm> using namespace std; typedef set<int> Set; map<Set, int> IDcache;//把集合映射成ID vector<Set> Setcache; //根据ID取集合 //查找给定集合x的ID。如果找不到,分配一个新的ID int ID(Set x) { if(IDcache.count(x)) return IDcache[x]; Setcache.push_back(x); //添加新集合 return IDcache[x] = Setcache.size() - 1; } //定义两个宏 #define ALL(x) x.begin(), x.end() #define INS(x) inserter(x, x.begin()) int main() { stack<int> s; int n, N; cin >> N; while(N--) { cin >> n; string op; for(int i = 0; i < n; i++) { cin >> op; if(op[0] == 'P') s.push(ID(Set())); else if(op[0] == 'D') s.push(s.top()); else { Set x1 = Setcache[s.top()]; s.pop(); Set x2 = Setcache[s.top()]; s.pop(); Set x; //set_unition(并集),set_intersection(交集),set_difference(差集) if(op[0] == 'U') set_union (ALL(x1), ALL(x2), INS(x)); if(op[0] == 'I') set_intersection (ALL(x1), ALL(x2), INS(x)); if(op[0] == 'A') {x = x2; x.insert(ID(x1)); } s.push(ID(x)); } cout << Setcache[s.top()].size() << endl; } cout << "***" << endl; } return 0; }