算法竞赛入门经典 第五章





  • [√] UVA12096 集合栈计算机 The SetStack Computer

    相关知识点 传送门

    $\color{green}{UVa12096}$
    #include<iostream>
    #include<stack>
    #include<set>
    #include<cstring>
    #include<map>
    #include<vector>
    #include<algorithm>
    #include <iterator>
    using namespace std;
    
    typedef set<int>Set;
    //给set<int>起个别名叫Set
    
    
    stack<int> s;
    map<Set, int> IDcache;
    vector<Set> Setcache;
    
    int ID(Set x) {//这个函数的参数是 整型集合
        if (IDcache.count(x)) //如果存在返回1,否则返回0
            return IDcache[x];//返回集合的编号
        Setcache.push_back(x);//否则添加新集合
        return IDcache[x] = Setcache.size() - 1;//分配编号,是第几个集合就分配第几
    }
    
    int main()
    {
        int t;
        cin >> t;
        while (t--) {
            int n;
            cin >> n;
            while (n--) {
                string op;
                cin >> op;
                if (op[0] == 'P') s.push(ID(Set()));//实例化一个空的set<int>传给函数ID
                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(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x,x.begin()));
                    if (op[0] == 'I') set_intersection(x1.begin(), x1.end(), x2.begin(), x2.end(), inserter(x, x.begin()));
                    if (op[0] == 'A') { x = x2;x.insert(ID(x1)); }
                    s.push(ID(x));
                }
                cout << Setcache[s.top()].size() << endl;
            }
            cout << "***" << endl;
        }
        return 0;
    }
    


  • [√] UVA136 丑数 Ugly Numbers

    数学题……嗯,题目意思不是三个因子都含有的数才叫丑数,是至少含有其中之一就可以了

    然后丑数的2倍、3倍、5倍都是丑数,注意这里可能出现重复,紫书上用set就是为了去重

    这里优先队列的话就记录一下队首元素的值,多次pop()直到下一个不同丑数为止

    $\color{green}{UVa136}$
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<iterator>
    #include<set>
    #include<queue>
    using namespace std;
    typedef long long ll;
    int main()
    {
      priority_queue<ll, vector<ll>, greater<ll> > q;
      q.push(1);
      for (int i = 1;;i++) {
          ll w = q.top();
          if (i == 1500) {
              cout << "The 1500'th ugly number is " << w<< "."<<endl;
              return 0;
          }
          q.push(w * 2);
          q.push(w * 3);
          q.push(w * 5);
          while (w == q.top()) q.pop();
      }
      return 0;
    }
    


  • [√] UVA1592 数据库 Database

    利用map.count()来判断是否已经出现过,如此就仅需要遍历一次n(行)。

    $\color{green}{UVa1592}$
    #include<iostream>
    #include<stack>
    #include<set>
    #include<cstring>
    #include<map>
    #include<vector>
    #include<algorithm>
    #include <iterator>
    using namespace std;
    
    //ID将字符串对应到唯一的编号,将整个表格v数字化
    //mp将编号的组合对应到列的组合
    
    long long v[10000 + 10][15];
    int n, m;
    string s1;
    int main() {
        while (cin >> n >> m) {
            int id = 0;
            map<string, int> ID;
            map<long long, int> mp;
            getchar();
            memset(v, 0, sizeof(v));
            int i, j;
            for (i = 1;i <= n;i++) {
                for (j = 1;j <= m;j++) {
                    s1.clear();
                    while (1) {
                        char ch = getchar();
                        if (ch == ',' || ch == '\n' || ch == '\r' || ch == EOF) break;
                        s1.push_back(ch);
                    }
                    if (ID.count(s1)) v[i][j] = ID[s1];
                    else v[i][j] = ID[s1] = ++id;
                }
            }
            int ok = 0;
            for (i = 1;i <= m;i++) {
                for (j = i + 1;j <= m;j++) {
                    mp.clear();
                    for (int k = 1;k <= n;k++) {
                        if (mp.count((long long)v[k][i] * 1000000 + v[k][j])) {
                            cout << "NO" << endl;
                            cout << mp[(long long)v[k][i] * 1000000 + v[k][j]] << " " << k << endl;
                            cout << i << " " << j << endl;
                            ok = 1;
                        }
                        else mp[(long long)v[k][i] * 1000000 + v[k][j]] = k;
                        if (ok) break;
                    }
                }
            }
            if (!ok) cout << "YES" << endl;
        }
        return 0;
    }
    



















posted @ 2020-03-25 18:57  StreamAzure  阅读(131)  评论(0编辑  收藏  举报