例题5-5 集合栈计算机(The Set Stack Computer,ACM/ICPC NWERC 2006,UVa12096)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/richenyunqi/article/details/86535481

欢迎访问我的Uva题解目录哦 https://blog.csdn.net/richenyunqi/article/details/81149109

题目描述

例题5-5 集合栈计算机(The Set Stack Computer,ACM/ICPC NWERC 2006,UVa12096)题目描述

题意解析

有一个专门为了集合运算而设计的“集合栈”计算机。该机器有一个初始为空的栈,并且支持以下操作:

  • PUSH:空集“{}”入栈。
  • DUP:把当前栈顶元素复制一份后再入栈。
  • UNION:出栈两个集合,然后把二者的并集入栈。
  • INTERSECT:出栈两个集合,然后把二者的交集入栈。
  • ADD:出栈两个集合,然后把先出栈的集合加入到后出栈的集合中,把结果入栈。

每次操作后,输出栈顶集合的大小(即元素个数)。
输入不超过2000个操作,并且保证操作均能顺利进行(不需要对空栈执行出栈操作)。

算法设计

参考了《算法竞赛与入门经典》书上的算法:

本题的集合并不是简单的整数集合或者字符串集合,而是集合的集合。为了方便起见此处为每个不同的集合分配一个唯一的ID,则每个集合都可以表示成所包含元素的ID集合,这样就可以用STL的set来表示了,而整个栈则是一个stack<int>。

该算法实际上就是将涉及到的集合存储到一个vector中,然后用vector中的下标来指代某一集合。用一个set<int>来表示一个集合,set<int>中的元素即为前面所说的vector的下标。

C++代码

#include<bits/stdc++.h>
using namespace std;
vector<set<int>>sets;//存储集合
map<set<int>,int>idCache;//集合与sets下标的映射关系
int ID(set<int>&s){//获取集合在sets中的下标
    if(idCache.find(s)==idCache.end()){//没有这一集合,分配一个新的id
        idCache[s]=sets.size();
        sets.push_back(s);
    }
    return idCache[s];
}
int main(){
    int T,N;
    cin>>T;
    while(T--){
        cin>>N;
        stack<int>s;
        string input;
        while(N--){
            cin>>input;
            if(input=="PUSH"){
                set<int>temp;
                s.push(ID(temp));
            }else if(input=="DUP"){
                s.push(ID(sets[s.top()]));
            }else{
                int id1=s.top();
                s.pop();
                int id2=s.top();
                s.pop();
                set<int>result;
                if(input=="UNION"){
                    set_union(sets[id1].begin(),sets[id1].end(),sets[id2].begin(),sets[id2].end(),inserter(result,result.begin()));
                }else if(input=="INTERSECT"){
                    set_intersection(sets[id1].begin(),sets[id1].end(),sets[id2].begin(),sets[id2].end(),inserter(result,result.begin()));
                }else if(input=="ADD"){
                    result=sets[id2];
                    result.insert(ID(sets[id1]));
                }
                s.push(ID(result));
            }
            cout<<sets[s.top()].size()<<endl;
        }
        cout<<"***"<<endl;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/richenyunqi/article/details/86535481