zoukankan      html  css  js  c++  java
  • 一个FLAG #14# The SetStack Computer

    集合栈计算机,完整题目见参考[1]

    书上的原始代码如下:

    #include <iostream>
    #include <vector>
    #include <map>
    #include <set>
    #include <string>
    #include <stack>
    #include <algorithm>
    // algorithm是必要的?否则 set_union报错 
    
    using namespace std;
    
    typedef set<int> Set;
    map<Set, int> ID_cache;
    vector<Set> Set_cache;
    
    // 查找指定集合的 id 如果找不到,分配一个新的 
    int ID(Set x) {
        if (ID_cache.count(x)) {
            return ID_cache[x]; // 返回相应 ID 
        } else {
            Set_cache.push_back(x); // 把集合放入集合cache中 
            return ID_cache[x] = Set_cache.size() - 1; 
            // 新分配ID也就是新集合在集合cache中的位置 
            // Set_cache[id] 就是那个对应的集合 
        }
    }
    
    #define ALL(x) x.begin(), x.end()
    #define INS(x) inserter(x, x.begin())
    
    int main()
    {
        stack<int> s; // 方便起见,为每个不同的集合,分配一个唯一的ID 
        
        int n;
        cin >> n;
        for (int i = 0; i != n; ++i) {
            string op;
            cin >> op;
            if (op[0] == 'P') {
                s.push(ID(Set()));
                // PUSH操作 空集{}入栈
                // 这里实际是创建了一个空的 set<int> 对象
                // 然后将其添加到 set_cache中 并分配了一个唯一的id
                // 通过 set_cache[id] 可以拿到这个集合,通过 IDcache[这个集合] 可以拿到它的id  
                // 通过ID()函数封装了这些操作。然后用id来充当集合进行操作 
            } else if (op[0] == 'D') {
                s.push(s.top());
                // DUP操作
                // 只是把一个数字push进去。集合本身没有拷贝
                // DUP多次的结果就是,栈中会有多个数字指向一个集合 
            } else {
                // UNION 以及 INTERSECT 以及 ADD操作首先都需要出栈两个集合
                Set x1 = Set_cache[s.top()]; // setcache中的集合是永不消除的 
                s.pop();
                Set x2 = Set_cache[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)); 
                    // 所以这个集合也是插入数字 并没有真正把集合插入到集合里去 
                    // 所以是用 set<int> 就可以 
                }
                s.push(ID(x));
            }
            cout << Set_cache[s.top()].size() << endl;
        }    
    }

    改了一下变量名,感觉还是没有很清晰。

    #include <iostream>
    #include <vector>
    #include <map>
    #include <set>
    #include <string>
    #include <stack>
    #include <algorithm>
    
    using namespace std;
    
    typedef set<int> MySet;
    map<MySet, int> ids; 
    vector<MySet> sets;  
    
    int getId(MySet mySet) {
        if (ids.count(mySet)) {
            return ids[mySet];
        } else {
            sets.push_back(mySet);
            return ids[mySet] = sets.size() - 1; 
        }
    }
    
    MySet getMySet(int id) {
        return sets[id];
    }
    
    #define ALL(x) x.begin(), x.end()
    #define INS(x) inserter(x, x.begin())
    
    int main()
    {
        stack<int> stack;
        
        int n;
        cin >> n;
        for (int i = 0; i != n; ++i) {
            string op;
            cin >> op;
            if (op[0] == 'P') {
                stack.push(getId(MySet()));
            } else if (op[0] == 'D') {
                stack.push(stack.top());
            } else {
                MySet set1 = getMySet(stack.top()); 
                stack.pop();
                MySet set2 = getMySet(stack.top());
                stack.pop();
                MySet set;
                if (op[0] == 'U') {
                    set_union(ALL(set1), ALL(set2), INS(set));
                }
                if (op[0] == 'I') {
                    set_intersection(ALL(set1), ALL(set2), INS(set));        
                }
                if (op[0] == 'A') {
                    set = set2;
                    set.insert(getId(set1)); 
                }
                stack.push(getId(set));
            }
            cout << getMySet(stack.top()).size() << endl;
        }    
    }

    参考

    [1] https://vjudge.net/problem/UVA-12096

  • 相关阅读:
    Oracle建立表空间和用户
    fscanf()函数具体解释
    三层架构(我的理解及具体分析)
    ListView嵌套ListView优化
    Android xml 解析
    玩转Web之servlet(三)---一张图看懂B/S架构
    jquery.scrollTo-min.js
    C#中MessageBox使用方法大全(附效果图)
    hdu 1882 Strange Billboard(位运算+枚举)
    MySQL 通配符学习小结
  • 原文地址:https://www.cnblogs.com/xkxf/p/12680031.html
Copyright © 2011-2022 走看看