zoukankan      html  css  js  c++  java
  • topcoder srm 715 div1

    problem1 link

    选择所有的'+'或者所有的‘-’,一定是这两种中的一种最大。

    problem2 link

    首先,第$n$个盘子初始时所在的柱子一定的最后所有的盘子都应该挪到的柱子。所以,可以枚举第$n$个盘子在哪个柱子上。

    假设目前枚举第$n$个盘子在第三个柱子上,那么假设要求解的问题为 $F(k,x,y,z,3)$, 其中$x=count[0],y=count[1],z=count[2]-1$,表示处理剩下的$n-1=x+y+z$个盘子,三根柱子上的个数为$(x,y,z)$。

    那么对于第$n-1$个盘子,如果也放到第三根柱子上,那么接下来就是求解$F(k,x,y,z-1,3)$。如果将其放置到第二根柱子上,那么要首先把把前面的$n-2$个盘子挪到第一根柱子上,然后挪$n-1$盘子,然后再把$n-2$个盘子挪到第三根上,这三步分别需要:$F(k^{'},x,y-1,z,1),1,2^{n-2}-1$ ,所以$k^{'}=k-2^{n-2}=k-2^{x+y+z-1}$,那么接下来要求解的是$F(k-2^{x+y+z-1},x,y-1,z,1)$。

    按照上面的思路可以得到结论如果$kgeq 2^{x+y+z-1}$,那么此时的盘子一定要换一根柱子。

    problem3 link

    这个就是直接搜索就可以了。把原来的树构造出来。

    code for problem1

    #include <algorithm>
    #include <string>
    
    class MaximumRange {
     public:
      int findMax(const std::string &s) {
        int n = static_cast<int>(s.size());
        int x = 0;
        for (auto c : s) {
          if (c == '+') {
            ++x;
          }
        }
        return std::max(x, n - x);
      }
    };

    code for problem2

    #include <string>
    #include <vector>
    
    class ClassicTowers {
     public:
      std::string findTowers(long long k, const std::vector<int> &count) {
        if (Check(k, count[0], count[1], count[2], "ABC")) {
          return result;
        }
        if (Check(k, count[0], count[2], count[1], "ACB")) {
          return result;
        }
        if (Check(k, count[1], count[2], count[0], "BCA")) {
          return result;
        }
        return "";
      }
    
     private:
      std::string result;
    
      std::vector<int> all;
    
      bool Dfs(long long k, int x, int y, int z, int idx) {
        if (x + y + z == 0) {
          return k == 0;
        }
        int curr = x + y + z - 1;
        if ((k & (1ll << curr)) == 0) {
          all[curr] = idx;
          if (idx == 1 && x > 0) {
            return Dfs(k, x - 1, y, z, idx);
          } else if (idx == 2 && y > 0) {
            return Dfs(k, x, y - 1, z, idx);
          } else if (idx == 3 && z > 0) {
            return Dfs(k, x, y, z - 1, idx);
          } else {
            return false;
          }
        } else {
          for (int i = 1; i <= 3; ++i) {
            if (i != idx) {
              all[curr] = i;
              if (i == 1 && x > 0 &&
                  Dfs(k ^ (1ll << curr), x - 1, y, z, 6 - idx - i)) {
                return true;
              }
              if (i == 2 && y > 0 &&
                  Dfs(k ^ (1ll << curr), x, y - 1, z, 6 - idx - i)) {
                return true;
              }
              if (i == 3 && z > 0 &&
                  Dfs(k ^ (1ll << curr), x, y, z - 1, 6 - idx - i)) {
                return true;
              }
            }
          }
          return false;
        }
      }
    
      bool Check(long long k, int x, int y, int z, const std::string &table) {
        if (z == 0) {
          return false;
        }
        long long maxk = (1ll << (x + y + z - 1)) - 1;
        if (k > maxk) {
          return false;
        }
        all.resize(x + y + z);
        all.back() = 3;
        if (Dfs(k, x, y, z - 1, 3)) {
          result = "";
          for (int i = 0; i < x + y + z; ++i) {
            result += table[all[i] - 1];
          }
          return true;
        }
        return false;
      }
    };

    code for problem3

    #include <algorithm>
    #include <map>
    #include <memory>
    #include <string>
    #include <vector>
    
    class PreInPost {
     public:
      std::vector<int> findMissing(const std::vector<std::string> &s,
                                   const std::vector<int> &a1,
                                   const std::vector<int> &a2,
                                   const std::string &e1, const std::string &e2) {
        table_s = s;
        auto status = Dfs(a1, a2, e1, e2);
        if (!status.flag) {
          return {};
        }
        std::vector<int> result;
        std::string mode = "pre";
        for (int i = 0; i < 6; i += 2) {
          if (s[i] != e1 && s[i] != e2) {
            Order(status.root.get(), s[i], &result);
            break;
          }
        }
        return result;
      }
    
     private:
      struct Node {
        int idx = -1;
        std::shared_ptr<Node> left = nullptr;
        std::shared_ptr<Node> right = nullptr;
    
        void SetRoot(int x) {
          if (idx == -1) {
            idx = x;
          } else if (idx != x) {
            idx = -2;
          }
        }
      };
    
      struct Status {
        std::shared_ptr<Node> root = nullptr;
        bool flag = false;
      };
    
      struct KeyNode {
        std::vector<int> a1;
        std::vector<int> a2;
        std::string e1;
        std::string e2;
    
        KeyNode() = default;
        KeyNode(const std::vector<int> &a1, const std::vector<int> &a2,
                const std::string &e1, const std::string &e2)
            : a1(a1), a2(a2), e1(e1), e2(e2) {}
    
        bool operator<(const KeyNode &key) const {
          if (a1 != key.a1) {
            return a1 < key.a1;
          }
          if (a2 != key.a2) {
            return a2 < key.a2;
          }
          if (e1 != key.e1) {
            return e1 < key.e1;
          }
          return e2 < key.e2;
        }
      };
      std::map<KeyNode, Status> visited_states;
      std::vector<std::string> table_s;
    
      int LeftModeIdx(const std::string &e) {
        if (e == "pre") {
          return 0;
        } else if (e == "in") {
          return 2;
        } else {
          return 4;
        }
      }
    
      void Order(const Node *node, const std::string &e, std::vector<int> *result) {
        if (node == nullptr) {
          return;
        }
        if (e == "pre") {
          result->push_back(node->idx);
          Order(node->left.get(), table_s[0], result);
          Order(node->right.get(), table_s[1], result);
        } else if (e == "in") {
          Order(node->left.get(), table_s[2], result);
          result->push_back(node->idx);
          Order(node->right.get(), table_s[3], result);
        } else {
          Order(node->left.get(), table_s[4], result);
          Order(node->right.get(), table_s[5], result);
          result->push_back(node->idx);
        }
      }
    
      bool SameSet(const std::vector<int> &a1, const std::vector<int> &a2) {
        long long s[4] = {0, 0, 0, 0};
        constexpr int kEach = 60;
        for (size_t i = 0; i < a1.size(); ++i) {
          s[a1[i] / kEach] ^= 1ll << (a1[i] % kEach);
          s[a2[i] / kEach] ^= 1ll << (a2[i] % kEach);
        }
        return s[0] == 0 && s[1] == 0 && s[2] == 0 && s[3] == 0;
      }
    
      Status Dfs(const std::vector<int> &a1, const std::vector<int> &a2,
                 const std::string &e1, const std::string &e2) {
        Status status;
        if (a1.empty()) {
          status.flag = true;
          return status;
        }
        status.root = std::shared_ptr<Node>(new Node);
        auto Set = [&](const std::vector<int> &a, const std::string &e) {
          if (e == "pre" || e == "post") {
            status.root->SetRoot(e == "pre" ? a.front() : a.back());
          }
        };
        Set(a1, e1);
        Set(a2, e2);
        if (status.root->idx == -2) {
          return status;
        }
        KeyNode key_node(a1, a2, e1, e2);
        if (visited_states.find(key_node) != visited_states.end()) {
          return visited_states[key_node];
        }
        std::vector<int> new_a1 = a1;
        std::vector<int> new_a2 = a2;
        int m = -1;
        auto RemoveRoot = [&](const std::string &e, std::vector<int> *a) {
          if (e == "pre") {
            a->erase(a->begin());
          } else if (e == "post") {
            a->pop_back();
          } else {
            m = static_cast<int>(std::find(a->begin(), a->end(), status.root->idx) -
                                 a->begin());
            a->erase(a->begin() + m);
          }
        };
        RemoveRoot(e1, &new_a1);
        RemoveRoot(e2, &new_a2);
        if (!SameSet(new_a1, new_a2)) {
          return visited_states[key_node] = status;
        }
        int n = static_cast<int>(new_a1.size());
        std::vector<int> right1;
        std::vector<int> right2;
        auto Check = [&]() {
          if (SameSet(new_a1, new_a2) && SameSet(right1, right2)) {
            Status left = Dfs(new_a1, new_a2, table_s[LeftModeIdx(e1)],
                              table_s[LeftModeIdx(e2)]);
            Status right = Dfs(right1, right2, table_s[LeftModeIdx(e1) + 1],
                               table_s[LeftModeIdx(e2) + 1]);
            if (left.flag && right.flag) {
              status.root->left = left.root;
              status.root->right = right.root;
              status.flag = true;
              return true;
            }
          }
          return false;
        };
    
        if (m == -1) {
          if (!Check()) {
            for (int i = n - 1; i >= 0; --i) {
              right1.insert(right1.begin(), new_a1.back());
              right2.insert(right2.begin(), new_a2.back());
              new_a1.pop_back();
              new_a2.pop_back();
              if (Check()) {
                break;
              }
            }
          }
        } else {
          for (int i = m; i < n; ++i) {
            right1.push_back(new_a1[i]);
            right2.push_back(new_a2[i]);
          }
          new_a1.erase(new_a1.begin() + m, new_a1.end());
          new_a2.erase(new_a2.begin() + m, new_a2.end());
          Check();
        }
        return visited_states[key_node] = status;
      }
    };
  • 相关阅读:
    搭建Java 开发环境
    自己制作 Android Vector Asset 矢量图
    Manifest merger failed with multiple errors, see logs 问题处理
    Android 获取所在城市(不接入地图SDK,使用android自带的SDK定位)
    根据视频地址获取封面
    Git 的一些使用细枝末节
    关于onActivityResult方法不执行的问题汇总
    关于handler 和 looper 的问题
    关于action和category的认知区别
    关于activity的生命周期的随笔
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/6951849.html
Copyright © 2011-2022 走看看