题意:一个“集合栈”,栈中的元素是集合。有以下几种操作。
PUSH:压入一个空集{} ,到栈顶。
DUP:取出栈顶元素,再压入(相当于复制了一份栈顶元素)
UNION:栈顶弹出两次。将两个元素(集合)作并操作。完成后压入栈顶。
INTERSECT:栈顶弹出两次。将两个元素(集合)作交操作。完成后压入栈顶。
ADD:取出栈顶两元素,先后获得A集合,B集合。将A集合作为B集合的元素加入到B集合。然后将B集合压入栈中
思路:用vecotr辅助编号,map映射集合。
#include<cstdio>
#include<algorithm>
#include<stack>
#include<set>
#include<map>
#include<vector>
using namespace std;
map<set<int>,int> m;//把集合映射成int ,一个集合对应一个数字
vector<set<int> > Get;
int setid(set<int> a)
{
if(m.count(a))return m[a];
Get.push_back(a);
return m[a]=Get.size()-1;
}
int main()
{
int t;
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
scanf("%d",&t);
while(t--)
{
int n;
stack<int> s;
scanf("%d",&n);
for(int i=0;i<n;i++)
{
char c[100];
scanf("%s",c);
if(c[0]=='P')s.push(setid(set<int>()));//调用默认构造函数生成对象
else if(c[0]=='D')s.push(s.top());
else
{
int a=s.top();s.pop();
int b=s.top();s.pop();
set<int> A=Get[a];
set<int> B=Get[b];
set<int> C;
if(c[0]=='U')
set_union(A.begin(),A.end(),B.begin(),B.end(),inserter(C,C.begin()));
else if(c[0]=='I')set_intersection(A.begin(),A.end(),B.begin(),B.end(),inserter(C,C.begin()));
else
{
B.insert(a);
C=B;
}
s.push(setid(C));
}
printf("%d\n",Get[s.top()].size());
}
printf("***\n");
}
}