题意:初始状态的栈内包含一个空集,对栈进行一下操作:
PUSH:向栈内压入一个空集
DUP:复制栈顶,并压入栈内
UNION:将栈顶端两个集合出栈,并将两个元素的并集入栈
INTERSECT:将栈顶端两个集合出栈,并将两个元素的交集入栈
ADD:将栈顶端两个集合出栈,将先出栈元素加入后出栈元素的集合中,而后入栈
对于每次操作,输出栈顶集合的元素数。
思路:声明一个栈st用来存放集合,声明多个堆用于表示集合,声明映射<set,int>表示集合编号,对于每次待入栈的集合进行编号查找工作,若已经有编号就将该编号入栈,否则赋予该集合一个编号,而后入栈。
对于并集操作使用:set_union()进行求解
对于交集操作使用:set_intersection()进行求解
#include<bits/stdc++.h> using namespace std; #define LL long long #define INF 999999999 typedef set<int> Set; map<Set,int>Map; stack<int> st; vector<Set> v; int Find(Set s) { if(Map.count(s)) return Map[s]; v.push_back(s); return Map[s] = v.size()-1; } int main() { int T,n; cin >> T; string s; while(T--) { cin >> n; Map.clear(); v.clear(); while(!st.empty()) st.pop(); for(int i=1;i<=n;i++) { cin >> s; if(s[0] == 'P') { st.push(Find(Set())); } else if(s[0]=='D') { st.push(st.top()); } else { Set s1 = v[st.top()]; st.pop(); Set s2 = v[st.top()]; st.pop(); Set temp; if(s[0]=='U') { set_union(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(temp,temp.begin())); } else if(s[0]=='I') { set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),inserter(temp,temp.begin())); } else if(s[0]=='A') { temp = s2; temp.insert(Find(s1)); } st.push(Find(temp)); } cout << v[st.top()].size() << endl; } cout << "***" << endl; } return 0; }