算法习题---5.5集合栈计算机(Uva12096)*****
一:题目
对于一个以集合为元素的栈,初始时栈为空。
输入的命令有如下几种:
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 ***
二:代码实现
(一)知识前提STL补充--set集合相等判断
(二)代码实现
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <map> #include <vector> #include <set> #include <stack> #include <string> #include <algorithm> using namespace std; typedef set<int> Set; vector<Set> Vec_Set_ID; //辅助获取集合对应ID号,其中每次只往里面添加新的集合 map<Set, int> Map_Set; //集合对应集合标识号,同上面vector,向其中添加新的集合和集合号 stack<int> Sta; //集合号栈 int GetIDForSet(Set s) { int number; if (Map_Set.count(s)) //如果直接找到了编号,则直接返回集合编号 return Map_Set[s]; //若是没有找到集合标号,先将该集合放入容器中之后获取编号 Vec_Set_ID.push_back(s); number = Vec_Set_ID.size() - 1; //重点:每个集合和其对应的编号与下标一致,方便寻找 Map_Set.insert(pair<Set, int>(s, number)); return number; } int main() { freopen("data5_5.in", "r", stdin); freopen("data5_5.out", "w", stdout); int count,oper_c; string cmd; cin >> count; while (count--) { cin >> oper_c; while (oper_c--) { cin >> cmd; //开始处理 if (cmd[0] == 'P') //入空集合 Sta.push(GetIDForSet(Set())); else if (cmd[0] == 'D') //栈顶集合复制一份入栈 Sta.push(Sta.top()); else { Set s; Set s1 = Vec_Set_ID[Sta.top()]; Sta.pop(); Set s2 = Vec_Set_ID[Sta.top()]; Sta.pop(); if (cmd[0] == 'U') //出栈两个集合将其并集入栈 set_union(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(s, s.begin())); else if (cmd[0] == 'I') set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(), inserter(s, s.begin())); else if (cmd[0] == 'A') { s2.insert(GetIDForSet(s1)); s = s2; } //进行插入栈中 Sta.push(GetIDForSet(s)); } //输出每一步栈顶集合的大小 cout << Vec_Set_ID[Sta.top()].size() << endl; } cout << "***" << endl; } freopen("CON", "r", stdin); freopen("CON", "w", stdout); return 0; }