背景:这个题对stl不熟悉根本无法自己作,只有照着理解书上的代码。
思路:用一个vector容器来储存集合,map中key为集合,value为该集合对应的vector容器的下标,并把下标称为ID,stack中储存的是ID每次对stack执行操作,实际是对stack中ID对应的集合执行操作用到了set_uinon和set_intersection。
#include<iostream>
#include<vector>
#include<map>
#include<algorithm> //set_union 和 set_interscetion 都在该头文件中,类似的还有set_difference差集
#include<set>
#include<stack>
#include<string>
using namespace std;
map<set<int>,int> map_list;
vector<set<int> > vector_ID;
set<int> setempty;
int ID(set<int> set_temp){ //输入一个集合,若该集合已经存在,直接返回ID,若不存在,新建一个map,并把该集合加入vector中。
if(map_list.count(set_temp)) return map_list[set_temp];
vector_ID.push_back(set_temp);
return map_list[set_temp]=vector_ID.size()-1;
}/*核心思想是用一个vector协助map完成对集合的ID化,最后计算集合内元素个数是,只需调用vector中对应的集合元素,用size函数*/
int main(void){
int n,t;
cin>>n;
while(n--){
cin>>t;
stack<int> stack_ID;
while(t--){
string operation;
cin >> operation;
if(operation == "PUSH") stack_ID.push(ID(setempty));
else if(operation == "DUP") stack_ID.push(stack_ID.top());
else{
set<int> x1=vector_ID[stack_ID.top()];stack_ID.pop();
set<int> x2=vector_ID[stack_ID.top()];stack_ID.pop();
set<int> x;
if(operation == "UNION") set_union(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(x,x.begin())); <span id="transmark"></span>//注意这里参数
if(operation == "INTERSECT") set_intersection(x1.begin(),x1.end(),x2.begin(),x2.end(),inserter(x,x.begin()));
if(operation == "ADD"){x=x2;x.insert(ID(x1));}
stack_ID.push(ID(x));
}
cout<<vector_ID[stack_ID.top()].size()<<endl;
}
cout<<"***"<<endl;
}
return 0;
}