一道好题,刚开始确实没思路,第一次用栈,冥思苦想,有了思路又无从下手,比着紫书搬了代码,写下来为了更好地总结和吸取经验,语言也比较通俗。
话不多说上代码 (=v=) y:
#include <iostream>
#include <algorithm>//STL内置集合操作(比如:∩ ∪)在这个里面
#include <vector>
#include <map>
#include <set>//怎么也想不到三个都用上了 QAQ
#include <stack>//使用栈要包含该头文件
using namespace std;
typedef set<int> SET;//set<int>简记SET 每个SET看作“一个集合”
#define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
vector<SET> Setcache;//元素为 集合 的 “集合库” && 集合角标(ID)<->集合
map<SET,int> IDcache;//集合(key) → ID(value) 注意是单向哦
int ID (SET x)
{
if(IDcache.count(x)) return IDcache[x];//若出现过 返回 集合x对应的ID
Setcache.push_back(x);//新面孔 加入 “集合库” 作为新元素
IDcache[x] = Setcache.size() - 1;//建立并记录对应关系
return IDcache[x];//返回 新集合x分配的ID
}
int main()
{
int T;cin >> T;
while(T--)
{
stack<int> s;//使用栈
int n;cin >> n;
while(n--)
{
string ps;cin >> ps;
if(ps[0]=='P') s.push( ID( SET() ) );//放入一个空栈
else if(ps[0]=='D') s.push( s.top() );//放入栈顶部集合
else{//出2
SET x1 = Setcache[s.top()]; s.pop();
SET x2 = Setcache[s.top()]; s.pop();
SET x;//将要放入的新集合,暂时为空
if(ps[0]=='U')
set_union (ALL(x1),ALL(x2),INS(x));
/* 内置函数,直接调用 */
if(ps[0]=='I')
set_intersection (ALL(x1),ALL(x2),INS(x));
if(ps[0]=='A') {x = x2;x.insert( ID(x1) );}
//if( x2.count( ID(x1) ) ) cout << "no"<<endl;~~
s.push( ID(x) );//进1
}
cout << Setcache[s.top()].size() << endl;
//输出 顶集合 元素个数
}
cout << "***" << endl;
}
return 0;
}
新年快乐~~~