思路: STL模拟
分析:
1 题目给定5种操作,每次输出栈顶集合的元素的个数
2 利用stack和set来模拟,set保存集合的元素。遇到push的时候直接在stack里面push入一个空的set,遇到Dup的时候把栈顶的集合在push进stack一次,遇到union的时候把栈顶的两个集合合并,遇到Intersect的时候把栈顶的两个集合进行求交集然后push进stack,遇到Add的时候要注意如果第一个集合是空集那么我们就认为是在第二个集合里面加入2,否则就要通过map来判断当前的集合所表示的值
代码:
#include<set> #include<map> #include<stack> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N = 20; const int MAXN = 2010; int cnt; stack<set<int> >stk; map<set<int> , int>mp; set<int>s1 , s2; void pop(){ s1 = stk.top(); stk.pop(); s2 = stk.top(); stk.pop(); } // push void Push(){ set<int>s; stk.push(s); puts("0"); } // dup void Dup(){ set<int>s; s = stk.top(); stk.push(s); printf("%d " , s.size()); } // union void Union(){ pop(); // set<int>::iterator it; for(it = s1.begin() ; it != s1.end() ; it++) s2.insert(*it); stk.push(s2); printf("%d " , s2.size()); } // Intersect void Intersect(){ pop(); // set<int>s3; set<int>::iterator it; for(it = s1.begin() ; it != s1.end() ; it++){ if(s2.find(*it) != s2.end()) s3.insert(*it); } stk.push(s3); printf("%d " , s3.size()); } // add void Add(){ pop(); // if(s1.empty()) s2.insert(0); else{ if(!mp[s1]) mp[s1] = cnt++; s2.insert(cnt++); } stk.push(s2); printf("%d " , s2.size()); } int main(){ int Case , n; char str[N]; scanf("%d" , &Case); while(Case--){ scanf("%d" , &n); while(!stk.empty()) stk.pop(); cnt = MAXN; mp.clear(); while(n--){ scanf("%s" , str); if(str[0] == 'P') Push(); else if(str[0] == 'D') Dup(); else if(str[0] == 'U') Union(); else if(str[0] == 'I') Intersect(); else Add(); } puts("***"); } return 0; }