UVa12096
这题理解起来有一些复杂,即使理解了一时也可能想不出来该怎么表示集合套集合的情况,后来看了看书,说用整数代表每一个集合。比如题目中的例子,可以定义A={0, 1}
,然后A
用2
表示,同样B={0, 3}
,然后B
用4
表示,A
和B
的并集中元素为{0, 1, 3}
,然后这个集合用5
表示,A
和B
的交集中元素为{0}
,这个集合用6
表示,A + B
中元素为{0, 3, 2}
,这个集合用7
表示。
书上不仅定义了一个编号到集合的映射,而且定义了一个集合到编号的映射。最开始的时候我只定义了编号到集合的映射vecsetNum2Set
,然后每做一次UNION、INTERSECT和ADD就添加一个新的编号到集合的映射关系,而不管是否和已有的重复,后来才发现这就无法保证元素的唯一性了。
#include <iostream>
#include <vector>
#include <set>
#include <string>
using namespace std;
void push(vector<int> &viStack, vector<set<int>> &vecsetNum2Set)
{
viStack.push_back(0);
if (vecsetNum2Set.size() <= 0) vecsetNum2Set.push_back(set<int>());
}
void dup(vector<int> &viStack, vector<set<int>> &vecsetNum2Set)
{
viStack.push_back(viStack.back());
}
void unionset(vector<int> &viStack, vector<set<int>> &vecsetNum2Set)
{
int top = viStack.back();
viStack.pop_back();
int sec = viStack.back();
viStack.pop_back();
set<int> si = vecsetNum2Set[top];
for (auto iter = vecsetNum2Set[sec].begin(); iter != vecsetNum2Set[sec].end(); iter++)
{
si.insert(*iter);
}
for (size_t idx = 0; idx < vecsetNum2Set.size(); idx++)
{
if (vecsetNum2Set[idx] == si){
viStack.push_back(idx);
return;
}
}
viStack.push_back(vecsetNum2Set.size());
vecsetNum2Set.push_back(si);
}
void intersect(vector<int> &viStack, vector<set<int>> &vecsetNum2Set)
{
int top = viStack.back();
viStack.pop_back();
int sec = viStack.back();
viStack.pop_back();
set<int> &siTop = vecsetNum2Set[top], si;
for (auto iter = siTop.begin(); iter != siTop.end(); iter++)
{
if (vecsetNum2Set[sec].find(*iter) != vecsetNum2Set[sec].end()){
si.insert(*iter);
}
}
for (size_t idx = 0; idx < vecsetNum2Set.size(); idx++)
{
if (vecsetNum2Set[idx] == si){
viStack.push_back(idx);
return;
}
}
viStack.push_back(vecsetNum2Set.size());
vecsetNum2Set.push_back(si);
}
void add(vector<int> &viStack, vector<set<int>> &vecsetNum2Set)
{
int top = viStack.back();
viStack.pop_back();
int sec = viStack.back();
viStack.pop_back();
set<int> si = vecsetNum2Set[sec];
si.insert(top);
for (size_t idx = 0; idx < vecsetNum2Set.size(); idx++)
{
if (vecsetNum2Set[idx] == si){
viStack.push_back(idx);
return;
}
}
viStack.push_back(vecsetNum2Set.size());
vecsetNum2Set.push_back(si);
}
int main()
{
int T = 0, ops = 0;
cin >> T;
for (int t = 0; t < T; t++)
{
cin >> ops;
string strOp;
vector<int> viStack;
vector<set<int>> vecsetNum2Set;
for (int i = 0; i < ops; i++)
{
cin >> strOp;
if (strOp == "PUSH"){
push(viStack, vecsetNum2Set);
}
else if (strOp == "DUP"){
dup(viStack, vecsetNum2Set);
}
else if (strOp == "UNION"){
unionset(viStack, vecsetNum2Set);
}
else if (strOp == "INTERSECT"){
intersect(viStack, vecsetNum2Set);
}
else if (strOp == "ADD"){
add(viStack, vecsetNum2Set);
}
cout << vecsetNum2Set[viStack.back()].size() << endl;
}
cout << "***" << endl;
//if (t == 42) return 0;
}
return 0;
}
/*
2
9
PUSH
DUP
ADD
PUSH
ADD
DUP
ADD
DUP
UNION
5
PUSH
PUSH
ADD
PUSH
INTERSECT
*/