topcoder srm 703 div1

problem1 link

按照$x$从小到大排序。然后从前向后处理,当前节点依次与前面已经处理的节点连边。

problem2 link

在$x$ 轴上有$n$个点A,$x$轴上方有$n$个点B,A集合中的每个点在B集合中的每个点找到一个匹配点,B集合中每个点只能与A中的一个点匹配,使得$n$条线段任意两条线段不相交。问有多少种方法。

思路:将B集合按照$y$坐标排序。A集合按照$x$排序。每次枚举A中的一个点与B中最高的点连线,这样分成两段,继续进行这样的匹配。

problem3 link

对每个节点进行哈希,找到同样的节点的个数,然后乘起来. 

 

code for problem1

#include <algorithm>
#include <vector>

class DAGConstruction {
 public:
  std::vector<int> construct(const std::vector<int> &x) {
    size_t n = x.size();
    std::vector<long long> f(n, 0);
    std::vector<int> ans, V;
    std::vector<std::pair<int, int>> p;
    for (size_t i = 0; i < n; ++i) {
      f[i] = 1ll << i;
      p.push_back(std::make_pair(x[i], i));
    }
    std::sort(p.begin(), p.end());
    auto Get = [&](long long x) {
      int cnt = 0;
      for (size_t i = 0; i < n; ++i) {
        if ((x & (1ll << i)) != 0) {
          ++cnt;
        }
      }
      return cnt;
    };
    for (size_t i = 0; i < n; ++i) {
      int c = p[i].first;
      int u = p[i].second;
      for (size_t j = 0; j < V.size(); ++j) {
        int t = V[V.size() - 1 - j];
        if (((f[u] & f[t]) != f[t]) && Get(f[u] | f[t]) <= c) {
          f[u] |= f[t];
          ans.push_back(u);
          ans.push_back(t);
        }
      }
      V.push_back(u);
      if (Get(f[u]) < c) {
        return {-1};
      }
    }
    return ans;
  }
};

code for problem2

#include <algorithm>
#include <map>
#include <vector>

class CoastGuard {
 public:
  static constexpr int kMod = 1000000007;

  int count(const std::vector<int> &d, const std::vector<int> &x,
            const std::vector<int> &y) {
    n = static_cast<int>(d.size());
    this->as = d;
    std::sort(as.begin(), as.end());
    bs.clear();
    cache.clear();
    cache.resize(n);
    std::vector<int> s(n);
    for (int i = 0; i < n; ++i) {
      bs.emplace_back(std::make_pair(x[i], y[i]));
      s[i] = i;
      cache[i].resize(n);
    }
    std::sort(bs.begin(), bs.end(),
              [&](const std::pair<int, int> &a, const std::pair<int, int> &b) {
                return a.second < b.second;
              });
    return Dfs(0, n - 1, s);
  }

 private:
  int Dfs(int L, int R, const std::vector<int> &s) {
    if (s.size() <= 1) {
      return 1;
    }
    {
      auto iter = cache[L][R].find(s);
      if (iter != cache[L][R].end()) {
        return iter->second;
      }
    }
    long long ans = 0;
    for (int i = L; i <= R; ++i) {
      int x1 = bs[s.back()].first - as[i];
      int y1 = bs[s.back()].second;
      std::vector<int> ls, rs;
      bool ok = true;
      for (size_t j = 0; j + 1 < s.size(); ++j) {
        int x0 = bs[s[j]].first - as[i];
        int y0 = bs[s[j]].second;
        int sgn = x0 * y1 - x1 * y0;
        if (sgn == 0) {
          ok = false;
          break;
        }
        if (sgn < 0) {
          ls.push_back(s[j]);
        } else {
          rs.push_back(s[j]);
        }
      }
      if (ok && ls.size() == i - L && rs.size() == R - i) {
        ans += 1ll * Dfs(L, i - 1, ls) * Dfs(i + 1, R, rs) % kMod;
      }
    }
    return cache[L][R][s] = static_cast<int>(ans % kMod);
  }

  std::vector<int> as;
  std::vector<std::pair<int, int>> bs;
  int n;
  std::vector<std::vector<std::map<std::vector<int>, int>>> cache;
};

code for problem3

#include <algorithm>
#include <vector>

class AutomorphicGraph {
 public:
  int count(int n, const std::vector<int> &a, const std::vector<int> &b) {
    std::vector<std::vector<int>> g(n);
    for (size_t i = 0; i < a.size(); ++i) {
      g[a[i]].emplace_back(b[i]);
      g[b[i]].emplace_back(a[i]);
    }
    auto Hash = [&](int num, std::vector<long long> *p) {
      constexpr int kMagicKey = 19891101;
      auto curr = *p;
      for (int t = 0; t < num; ++t) {
        for (int i = 0; i < n; ++i) {
          std::vector<long long> values(g[i].size());
          for (size_t j = 0; j < g[i].size(); ++j) {
            values[j] = p->at(g[i][j]);
          }
          std::sort(values.begin(), values.end());
          for (long long v : values) {
            curr[i] = curr[i] * kMagicKey + v;
          }
        }
        *p = curr;
      }
    };
    constexpr int kMod = 1000000007;
    long long result = 1;
    std::vector<int> visit(n, 0);
    std::vector<long long> ss(n, 0);
    for (int i = 0; i < n; ++i) {
      std::vector<long long> p(n, 0);
      for (int j = i; j < n; ++j) {
        for (int k = 0; k < n; ++k) {
          p[k] = visit[k] + n;
        }
        p[j] += 1;
        Hash(6, &p);
        ss[j] = p[j];
      }
      Hash(n + 10, &ss);
      int c = 0;
      for (int j = i; j < n; ++j) {
        if (ss[j] == ss[i]) {
          ++c;
        }
      }
      result = result * c % kMod;
      visit[i] = i + n + 1;
    }
    return static_cast<int>(result);
  }
};

DAGConstruction

posted @ 2017-04-12 21:14  朝拜明天19891101  阅读(196)  评论(0编辑  收藏  举报