topcoder srm 630 div1
阿新 • • 發佈:2018-11-17
problem1 link
首先計算任意兩點的距離。然後列舉選出的集合中的兩個點,判斷其他點是否可以即可。
problem2 link
假設字串為$s$,長度為$n$。那麼對於$SA$中的兩個排名$SA_{i},SA_{i+1}$來說,應該儘量使得$s[SA_{i}]=s[SA_{i+1}]$。如果這個滿足的話,那麼需要兩個字尾滿足$s[SA_{i}+1\sim n-1]<s[SA_{i+1}+1\sim n-1]$,設他們的排名分別為$SA_{r},SA_{k}$,也就是說$r<k$即可。
problem3 link
code for problem1
#include <algorithm> #include <unordered_set> #include <vector> class Egalitarianism3 { public: int maxCities(int n, const std::vector<int> &a, const std::vector<int> &b, const std::vector<int> &len) { if (n == 1) { return 1; } std::vector<std::vector<int>> g(n, std::vector<int>(n, -1)); for (int i = 0; i < n - 1; ++i) { g[a[i] - 1][b[i] - 1] = g[b[i] - 1][a[i] - 1] = len[i]; } for (int i = 0; i < n; ++i) { g[i][i] = 0; } for (int i = 0; i < n; ++i) { for (int u = 0; u < n; ++u) { if (g[u][i] != -1) { for (int v = 0; v < n; ++v) { if (g[i][v] != -1) { if (g[u][v] == -1 || g[u][v] > g[u][i] + g[i][v]) { g[u][v] = g[u][i] + g[i][v]; } } } } } } auto Compute = [&](int s, int t) { std::unordered_set<int> all; all.insert(s); all.insert(t); const int d = g[s][t]; for (int i = 0; i < n; ++i) { if (all.find(i) == all.end()) { bool tag = true; for (auto e : all) { if (g[i][e] != d) { tag = false; break; } } if (tag) { all.insert(i); } } } return static_cast<int>(all.size()); }; int result = 0; for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { result = std::max(result, Compute(i, j)); } } return result; } };
code for problem2
#include <vector> class SuffixArrayDiv1 { public: int minimalCharacters(const std::vector<int> &SA) { int n = static_cast<int>(SA.size()); std::vector<int> s(n + 1, -1); for (int i = 0; i < n; ++i) { s[SA[i]] = i; } int result = 1; for (int i = 0; i + 1 < n; ++i) { if (s[SA[i] + 1] > s[SA[i + 1] + 1]) { ++result; } } return result; } };
code for problem3