• 算法入门经典-第五章 例题 5-5 集合栈计算机


    The SetStack Computer

    Time limit: 3.000 seconds

    题目是这样的:

           有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且支持以下操作:
    PUSH:空集“{}”入栈
    DUP:把当前栈顶元素复制一份后再入栈
    UNION:出栈两个集合,然后把两者的并集入栈
    INTERSECT:出栈两个集合,然后把二者的交集入栈
    ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈
           每次操作后,输出栈顶集合的大小(即元素个数)。例如栈顶元素是A={ {}, {{}} }, 下一个元素是B={ {}, {{{}}} },则:
    UNION操作将得到{ {}, {{}}, {{{}}} },输出3.
    INTERSECT操作将得到{ {} },输出1
    ADD操作将得到{ {}, {{{}}}, { {}, {{}} } },输出3.
    (输入:先输入测试次数,再输入操作次数,再输入具体操作)
    Sample Input
    2
    9
    PUSH
    DUP
    ADD
    PUSH
    ADD
    DUP
    ADD
    DUP
    UNION
    5
    PUSH
    PUSH
    ADD
    PUSH
    INTERSECT

    Sample Output
    0
    0
    1
    0
    1
    1
    2
    ***
    0
    0
    1
    0
    0

    ***

    【分析】

           为每个不同的集合分配一个唯一的ID,则每个集合都可以表示成所包含元素的ID集合,这样就可以用STL的set<int>来表示了,而整个栈则是一个stack<int>。

    用C++语言编写程序,代码如下:

    #include<iostream>
    #include<string>
    #include<set>
    #include<map>
    #include<stack>
    #include<vector>
    #include<algorithm>
    using namespace std;
    
    typedef set<int> Set;
    //定义一个int型集合对象Set,当前没有任何元素.
    map<Set,int> IDcache;//把集合映射成ID
    vector<Set> Setcache;
    //查找集合的ID.如果找不到,分配一个新ID
    int ID(Set x)
    {
        if(IDcache.count(x)) return IDcache[x];
        Setcache.push_back(x);
        return IDcache[x]=Setcache.size()-1;
    }
    #define All(x) x.begin(),x.end()
    #define INS(x) inserter(x,x.begin())
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            stack<int> s;
            int i,n;
            cin>>n;
            for(i=0; i<n; i++)
            {
                string op;
                cin>>op;
                if(op[0]=='P') s.push(ID(Set()));
                else if(op[0]=='D') s.push(s.top());
                else
                {
                    Set x1=Setcache[s.top()];
                    s.pop();
                    Set x2=Setcache[s.top()];
                    s.pop();
                    Set x;
                    if(op[0]=='U') set_union(All(x1),All(x2),INS(x));
                    if(op[0]=='I') set_intersection(All(x1),All(x2),INS(x));
                    if(op[0]=='A')
                    {
                        x=x2;
                        x.insert(ID(x1));
                    }
                    s.push(ID(x));
                }
                cout<<Setcache[s.top()].size()<<endl;
            }
        }
    return 0;
    }
    

    刘汝佳标程用的是Set到int的映射

  • 相关阅读:
    一个小厂算法工程师的2021个人年终总结
    优达学城 UdaCity 纳米学位
    Eclipse 常用可视化开发插件
    Android创建文件夹和文件
    Windows Mobile 播放声音文件
    C++实现顺序栈类
    c++实现的图类
    常见的字符串操作
    常见的链表操作
    取余数法实现哈希表(包括开放定址法和链地址法解决冲突)
  • 原文地址:https://www.cnblogs.com/is-Tina/p/7351199.html
Copyright © 2020-2023  润新知