标签:
PS:因为该题排版较麻烦,这里给出OJ网址:UVa12096 - The SetStack Computer
有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且支持以下操作。
- PUSH:空集“{}”入栈。
- DUP:把当前栈顶元素复制一份后再入栈。
- UNION:出栈两个集合,然后把二者的并集入栈。
- INTERSECT:出栈两个集合,然后把二者的交集入栈。
- ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈。
每次操作后,输出栈顶集合的大小(即元素个数)。例如,栈顶元素是A={{},{{}}},下一个元素是B={{},{{{}}}},则:
- UNION操作将得到{{},{{}},{{{}}}},输出3。
- INTERSECT操作将得到{{}},输出1。
- ADD操作将得到{{},{{{}}},{{},{{}}}},输出3。
输入不超过2000个操作,并且保证操作均能顺利进行(不需要对空栈执行出栈操作)。
#include <iostream>
#include <string>
#include <stack>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;
// 设计思路:
// map只能获取key->value这样的关联
// 如果想通过value->key就必须再添加另一种辅助容器
// 在这是通过vector容器实现value->key,也就是说具有以下关系
// idCache[x] 为集合x的id
// setCache[idCache[x]] 就是x集合本身
// set<int>为集合,int为id
map<set<int>, int> idCache;
// 缓存set集合
vector<set<int> > setCache;
// 查找给定集合s的ID,如果未找到,分配一个新ID
int ID(set<int> s) {
if(idCache.count(s)) {
return idCache[s];
}
// 将集合x加入到set缓存中
setCache.push_back(s);
// 将集合x在缓存中的位置,作为唯一ID
return idCache[s] = setCache.size() - 1;
}
int main() {
int T;
cin >> T;
while(T--) {
// 集合栈
stack<int> s;
int n;
cin >> n;
for(int i = 0; i < n; i++) {
// 操作
string op;
cin >> op;
// PUSH
if(op[0] == ‘P‘) {
// 将空集入栈
s.push(ID(set<int>()));
} else if(op[0] == ‘D‘) {
// DUP
// 将栈顶元素再次入栈
s.push(s.top());
} else {
// 取出栈顶的两个元素
set<int> x1 = setCache[s.top()];
s.pop();
set<int> x2 = setCache[s.top()];
s.pop();
set<int> x;
// UNION
if(op[0] == ‘U‘) {
// 1,2参数为集合x1的元素开始结束位置迭代器
// 3,4参数为集合x2的元素开始结束位置迭代器
// 5参数代表插入迭代器
set_union(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x, x.begin()));
}
// INTERSECT
if(op[0] == ‘I‘) {
set_intersection(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x, x.begin()));
}
// ADD
if(op[0] == ‘A‘) {
x = x2;
x.insert(ID(x1));
}
s.push(ID(x));
}
cout << setCache[s.top()].size() << endl;
}
cout << "***" << endl;
}
return 0;
}
标签:
原文地址:http://blog.csdn.net/q547550831/article/details/51331876