zoukankan      html  css  js  c++  java
  • UVA12096 集合栈计算机(map和vector实现双射关系+集合的交并运算的STL)

    题目大意:

    对于一个以集合为元素的栈,初始时栈为空。

    输入的命令有如下几种:

    PUSH:将空集{}压栈

    DUP:将栈顶元素复制一份压入栈中

    UNION:先进行两次弹栈,将获得的集合A和B取集,将结果压栈

    INTERSECTION:先进行两次弹栈,将获得的集合A和B取集,将结果压栈

    ADD:先进行两次弹栈,将获得的集合A和B中,先出栈的集合(如A先)加入到后出栈的集合,将结果压栈

    输出每一步操作后栈顶集合的元素的个数。

    题目详细信息见传送门

    思路如下:

    对于集合的集合,我们很难直接表示,因此,我们可以换一种想法,既然集合的集合难以表示,我们就只需要给每种集合一个唯一的ID就可以了,这样,集合中的元素就可以通过ID来表示。一个集合就可以表示为一个set<int>

    在这里,我们使用STL中的set进行表示,就会容易很多,加入栈中的元素也就可以是int类型了

    在进行操作时,我们可以用map将每种集合与对应的ID关联起来,这样做既可以完成查找ID的任务,还可以同时判定是否出现了新的集合。

    我们可以用vector作为存储每种集合的cache,这样,每当map中没有相应的ID时,我们就向vector中加入一个set<int>元素,并将下标作为ID进行唯一的标识。

    使用vector将set存储起来的好处是,反过来我们也可以用ID查询到对应的set,这样,通过map和vector,我们实现了set 到ID 的双射

    最后,输出栈顶集合的size属性,即可。

    代码如下:

     1     //UVA12096 集合栈计算机 
     2     #include<cstdio>
     3     #include<iostream>
     4     #include<algorithm>//set_union等函数定义在这里 
     5     #include<vector>
     6     #include<set>
     7     #include<map>
     8     #include<stack>
     9     
    10     #define ALL(x) x.begin(),x.end()
    11     #define INS(x) inserter(x,x.begin()) //注意宏的括号和inserter 
    12     
    13     using namespace std;
    14     
    15     typedef set<int> Set;
    16     map<Set,int> IDCache;
    17     vector<Set> setCache;
    18     int t,n;
    19     char cmd[10];
    20     int getID(Set s){
    21         if(IDCache.count(s))return IDCache[s];
    22         setCache.push_back(s);  //将新集合加入Setcache 
    23         return IDCache[s]=setCache.size()-1;//将ID加入map ,同时返回新分配的ID值 
    24     }
    25     
    26     int main(){
    27         scanf("%d",&t);
    28         while(t--){
    29             scanf("%d",&n);
    30 //            setCache.clear(); 
    31             stack<int> s;
    32             while(n--){
    33                 scanf(" %s",&cmd);
    34                 if(cmd[0]=='P')s.push(getID(Set()));
    35                 else if(cmd[0]=='D')s.push(s.top());
    36                 else{
    37                     Set s1=setCache[s.top()];s.pop();
    38                     Set s2=setCache[s.top()];s.pop();
    39                     Set x;
    40                     if(cmd[0]=='U')set_union(ALL(s1),ALL(s2),INS(x));
    41                     if(cmd[0]=='I')set_intersection(ALL(s1),ALL(s2),INS(x));
    42                     if(cmd[0]=='A'){ x=s2; x.insert(getID(s1)); }
    43                     s.push(getID(x));
    44                 }
    45                 printf("%d
    ",setCache[s.top()].size());
    46             }
    47             puts("***");
    48         }
    49     }

     

    注意:

      第30行的setCache.clear()是必须注释掉的,因为如果存在这一句,那么vector就会清空,但是对应的map却没有清空,就会出现wa的情况。

      从另一个角度说,只需要map和vector始终保持一致那么set和ID 的双射关系就不会发生改变,此时我们就不需要将map和vector清空,因为不影响后续操作的结果。

  • 相关阅读:
    QTableWidget控件总结<一>
    软件工程概论9
    软件工程概论8
    软件工程概论7
    软件工程概论6
    软件工程概论5
    软件工程概论4
    软件工程概论3
    软件工程概论2
    安装gocode教程
  • 原文地址:https://www.cnblogs.com/luruiyuan/p/5782852.html
Copyright © 2011-2022 走看看