スタック収集コンピュータ(設定スタックコンピュータ、ACM / ICPC NWERC 2006、UVa12096)
コレクションの収集のために、直接発現することが困難であり、従って、便宜上、異なるIDを割り当てごとに異なるセットのために、各セットは、セットの集合として表すことができ、コレクションに含まれるセットIDとして表すことができます。
我的理解:
{}:1 {{}} 2
栈中的都是集合,所以也是int类型的
実際の動作時には、各マップやIDまでの対応するセットに関連付けることが可能であるので、我々は、タスクを完了するためのIDを見つけることができること、それはまた、新しいコレクションがあると同時にかどうかを判断することができます。
キャッシュメモリのセットとして各ベクトルと、そこには、対応するマップIDがなく、私はセットにベクターに連結するたびよう
ベクターセットを使用する利点は、順番に、我々はまた、対応するセットにクエリIDを使用することができ、保存されているので、マップとベクトルによって、我々はIDにダブルショットセットを達成しました。
//聚合栈计算机
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
typedef set<int> Set;
map<Set,int> IDcache;
vector<Set>Setcache;
int ID(Set x)
{
if(IDcache.count(x)) return IDcache[x]; //map中已有key(x),返回对应的value值
Setcache.push_back(x); //map中没有key(x),将其插入vector 中
return IDcache[x]=Setcache.size()-1; //将key(x)存入map中,并将对应的value赋值为在vector中的下标
}
int main()
{
int n,k;
stack<int> s;
cin>>n;
while(n--)
{
cin>>k;
while(k--)
{
string str;
cin>>str;
if(str[0]=='P') s.push(ID(set())); //空集入栈
else if(str[0]='D') s.push(s.top()); //把当前栈顶元素复制一份后再入栈
//剩下的三种操作,涉及到ID
else
{
Set x1 = Setcache[s.top()]; s.pop(); //栈顶第一个集合 (注意:s.top()是一个id)
Set x2 = Setcache[s.top()]; s.pop(); //第二个
Set x; //有一个取并,交的新的集合
if (str[0] == 'U') set_union(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x, x.begin()));
if (str[0] == 'I') set_intersection(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x, x.begin()));
if (str[0] == 'A') { x = x2; x.insert(ID(x1)); } //将x1的ID插入到x中
s.push(ID(x)); //合并后的x存入vector中,再将ID压入栈中
}
cout << Setcache[s.top()].size() << endl;
}
}
return 0;
}