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)$。

按照上面的思路可以得到结论如果$k\geq 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;
  }
};
posted @ 2017-06-06 15:32  朝拜明天19891101  阅读(360)  评论(0编辑  收藏  举报