比赛链接:Here

1547A. Shortest Path with Obstacle

3个点 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图1 ,前提 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图2 点为不可经过点,问 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图3 最短路径长度


A题没什么难度,注意同列和同行在两者之间的情况即可

【AC Code】

  1. int main() {
  2. cin.tie(nullptr)->sync_with_stdio(false);
  3. int _; for (cin >> _; _--;) {
  4. int a, b, c, d, e, f;
  5. cin >> a >> b >> c >> d >> e >> f;
  6. int s = abs(a - c) + abs(b - d);
  7. if (a == c && a == e && (f > b && f < d || f > d && f < b) || b == d && b == f && (e > a && e < c || e > c && e < a))
  8. s += 2;
  9. cout << s << '\n';
  10. }
  11. }

1547B. Alphabetical Strings

构造出一个按 字母序的字符串

  • 首先,构造空串
  • 重复 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图4 次:Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图5 or Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图6

  • 首先,我们如果可以找出字母“a”在字符串s中的位置。如果这个位置不存在,那么答案是 NO

  • 假设这个位置存在并且等于 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图7。让我们创建两个指针L和R。最初 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图8Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图9。我们将尝试使用语句中的算法来左右构建字符串 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图10
    当我们能迭代 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图11 次时输出 YES,否则 输出 NO

【AC Code】

  1. int main() {
  2. cin.tie(nullptr)->sync_with_stdio(false);
  3. int _; for (cin >> _; _--;) {
  4. function<int(string)> check = [&](string s) {
  5. if (s.empty())return 1;
  6. if (s[0] == 'a' + s.size() - 1)return check(s.substr(1));
  7. if (s.back() == 'a' + s.size() - 1)return check(s.substr(0, s.size() - 1));
  8. return 0;
  9. };
  10. string s; cin >> s;
  11. cout << (check(s) ? "YES\n" : "NO\n");
  12. }
  13. }

1547C. Pair Programming

一项工作有 Monocarp 和 Polycarp 两人各 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图12Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图13 工时合作完成

他们都有两种操作:

  • 0,新添加一行
  • x > 0 ,在第 x 行上修改为 x

但这项工作原本已经存在 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图14 行被完成,请 Monocarp 和 Polycarp 操作的任何正确公共序列,如果不存在则输出 -1


模拟,

对于两人的操作 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图15 是不能超过 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图16 的,所以使用双指针模拟两人的操作即可

【AC Code】

  1. int main() {
  2. cin.tie(nullptr)->sync_with_stdio(false);
  3. int _; for (cin >> _; _--;) {
  4. int k, n, m;
  5. cin >> k >> n >> m;
  6. vector<int>a(n), b(m), ans;
  7. for (int &x : a)cin >> x;
  8. for (int &x : b)cin >> x;
  9. for (int i = 0, j = 0; i < n or j < m;) {
  10. if (i < n and a[i] <= k) {
  11. k += a[i] == 0;
  12. ans.push_back(a[i++]);
  13. } else if (j < m and b[j] <= k) {
  14. k += b[j] == 0;
  15. ans.push_back(b[j++]);
  16. } else break;
  17. }
  18. if (ans.size() != n + m)cout << "-1\n";
  19. else {
  20. for (int i : ans)cout << i << " ";
  21. cout << "\n";
  22. }
  23. }
  24. }

1547D. Co-growing Sequence

  • 如同 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图17
    $[0,0,0] \to [0_2,0_2,0_2] $
    均为增长序列

现在给一个长度为 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图18Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图19 数组,请输出一组 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图20 使得 Codeforces Round #731 (Div. 3) A~G (G 树形DP) - 图21 为增长序列


思路待补

【AC Code】

  1. int main() {
  2. cin.tie(nullptr)->sync_with_stdio(false);
  3. int _; for (cin >> _; _--;) {
  4. int n; cin >> n;
  5. int x, p = 0;
  6. for (int i = 0; i < n; ++i) {
  7. cin >> x;
  8. cout << (p | x) - x << " ";
  9. p |= x;
  10. }
  11. cout << "\n";
  12. }
  13. }

1547E. Air Conditioners

对于每个位置的空调的最小值来说肯定是和左右(+1)比较

【AC Code】

  1. int main() {
  2. cin.tie(nullptr)->sync_with_stdio(false);
  3. int _; for (cin >> _; _--;) {
  4. int n, k;
  5. cin >> n >> k;
  6. vector<int> a(n, 2e9), v(k), t(k);
  7. for (int &x : v) cin >> x;
  8. for (int &x : t) cin >> x;
  9. for (int i = 0; i < k; ++i)a[v[i] - 1] = t[i];
  10. for (int i = 1; i < n; ++i) a[i] = min(a[i - 1] + 1, a[i]);
  11. for (int i = n - 2; i >= 0; --i)a[i] = min(a[i + 1] + 1, a[i]);
  12. for (int x : a)cout << x << " ";
  13. cout << "\n";
  14. }
  15. }

1547F. Array Stabilization (GCD version)

【AC Code】

  1. int main() {
  2. cin.tie(nullptr)->sync_with_stdio(false);
  3. int _; for (cin >> _; _--;) {
  4. int n, d = 0;
  5. cin >> n;
  6. vector<int> v(n * 2);
  7. for (int i = 0; i < n; i++) {
  8. cin >> v[i];
  9. v[i + n] = v[i];
  10. d = __gcd(d, v[i]);
  11. }
  12. int ans = 0;
  13. vector<pair<int, int>>vt;
  14. for (int i = 2 * n - 1; i >= 0; i--) {
  15. vector<pair<int, int>> wp;
  16. vt.push_back({0, i});
  17. for (auto [x, y] : vt) {
  18. x = __gcd(x, v[i]);
  19. if (not wp.empty() and x == wp.back().first) wp.back().second = y;
  20. else wp.push_back({x, y});
  21. }
  22. swap(vt, wp);
  23. if (i < n) ans = max(ans, vt[0].second - i);
  24. }
  25. cout << ans << "\n";
  26. }
  27. }

1547G. How Many Paths?

邻接表 + 树形DP

【AC Code】

  1. int main() {
  2. cin.tie(nullptr)->sync_with_stdio(false);
  3. int _; for (cin >> _; _--;) {
  4. int n, m;
  5. cin >> n >> m;
  6. vector<vector<int>> G(n), H(n);
  7. for (int i = 0, u, v; i < m; i += 1) {
  8. cin >> u >> v;
  9. u -= 1;
  10. v -= 1;
  11. G[u].push_back(v);
  12. H[v].push_back(u);
  13. }
  14. vector<int> order, id(n);
  15. function<void(int)> dfs1 = [&](int u) {
  16. id[u] = -1;
  17. for (int v : H[u])
  18. if (not id[v])dfs1(v);
  19. order.push_back(u);
  20. };
  21. for (int i = 0; i < n; i += 1) if (not id[i]) dfs1(i);
  22. reverse(order.begin(), order.end());
  23. int count = 0;
  24. function<void(int)> dfs2 = [&](int u) {
  25. id[u] = count;
  26. for (int v : G[u])
  27. if (not ~id[v])
  28. dfs2(v);
  29. };
  30. for (int i : order) if (not ~id[i]) {
  31. dfs2(i);
  32. count += 1;
  33. }
  34. vector<vector<int>> g(count);
  35. for (int i = 0; i < n; i += 1)
  36. for (int j : G[i]) {
  37. g[id[i]].push_back(id[j]);
  38. assert(id[i] >= id[j]);
  39. }
  40. vector<int> dp(count);
  41. for (int i = id[0]; i >= 0; i -= 1) {
  42. if (i == id[0]) dp[i] = 1;
  43. if (dp[i]) {
  44. for (int j : g[i]) if (j == i) dp[i] = -1;
  45. }
  46. for (int j : g[i]) {
  47. if (dp[i] == -1) dp[j] = -1;
  48. if (dp[i] == 2 and dp[j] != -1) dp[j] = 2;
  49. if (dp[i] == 1 and dp[j] != -1 and dp[j] <= 1) dp[j] += 1;
  50. }
  51. }
  52. for (int i = 0; i < n; i += 1) cout << dp[id[i]] << " ";
  53. cout << "\n";
  54. }
  55. }