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

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

首先定义了个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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值