例题5-5 UVA 12096 The SetStack Computer集合栈计算机

时间:2022-09-03 00:26:39

有关于栈的一道题,看了很长时间,还是晕晕乎乎,记录一下自己的一点收获吧!

首先定义了个typedef set<int >Set用来后面开空集合方便:开空集合直接Set()就可以了!

接着用到了map<Set,int>IDcaches就是把Set与int 一 一对应,这里的int也就是Set集合的ID,

然后又开了一个Vector<Set>Setcaches用来存储Set集合

然后开一个stack<int>s建立一个栈,后面的一系列命令全都是围绕着这个stack<int>s进行的,这里stack<int >,就意味着往里面放东西的时候,放的是int数据!

又写了一个ID函数,这个函数是,输入一个Set集合,返回一个ID,如果这个集合存在的话,就直接返回已存在的ID,如果不存在,则先往Setcaches(存集合的地方!)push_back这个集合,在返回一个新的ID,这里返回的是IDcaches[x].size() - 1;之所以返回size - 1,是因为Vector,push_back是从0开始的,然后元素个数是从1开始的(如果元素存在的话),所以要让元素个数减一在和那个集合进行匹配,举个例子吧:如果一开始栈里面什么也没有,则元素个数(size)为0,如果放一个空集,则元素个数,size = 1,然而他的下标为0,所以要让size - 1;

整体思路呢:

输入输出格式就不说了,就是先判断命令,在执行命令,例如PUSH命令:压栈一个空集,就是s.push(ID(set())),值得注意的是,因为stack存的是int类型,所以,s.push()也一定是一个数字,所以不是数字的就直接加个ID()返回一个数字(ID)就可以了,

在一点呢,判断命令时有一个技巧,先观察各个命令,发现后面三个命令都是先提出栈的前两个元素,所以代码直接找到命令的共性,把后三个写到了一起。

在一点,s.top()是返回一个int类型,因为,stack是<int>的:

s.pop()取出栈顶元素,但不删除。

经常看,经常练习,相信一定会熟练掌握的!

#include<iostream>
#include<map>
#include<set>
#include<vector>
#include<stack>
#include<algorithm>
#define All(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin())
using namespace std;
stack<int>s;
typedef set<int>Set;
map<Set,int>IDcaches;
vector<Set>Setcaches;
int ID(Set x){
if (IDcaches.count(x))return IDcaches[x];
Setcaches.push_back(x);
return IDcaches[x] = Setcaches.size() - 1;
}
int main()
{
int T,N;
cin >> T;
while(T--){
cin >> N;
for (int i = 0; i < N; ++i){
string str;
cin >> str;
if (str[0] == 'P')s.push(ID(Set()));
else if (str[0] == 'D')s.push(s.top());
else {
Set x1 = Setcaches[s.top()];s.pop();
Set x2 = Setcaches[s.top()];s.pop();
Set x;
if (str[0] == 'U')set_union(All(x1),All(x2),INS(x));
if (str[0] == 'I')set_intersection(All(x1),All(x2),INS(x));
if (str[0] == 'A'){x = x2; x.insert(ID(x1));}
s.push(ID(x));
}
cout << Setcaches[s.top()].size() << endl;
}
cout << "***" << endl;

}


return 0;
}