A. Wizard of Orz

题意:给定一排 Codeforces Round #695 (Div. 2) - 图1 个个位计时器,每秒都会 +1,并且 9 + 1 = 0。如果在某瞬间暂停某个计时器,那下一秒 Codeforces Round #695 (Div. 2) - 图2 Codeforces Round #695 (Div. 2) - 图3也会停止,以此类推至全部计时器停止,问在那秒停止会使显示的数字最大。

思路:要使显示数字最大,使首位为 Codeforces Round #695 (Div. 2) - 图4 即可,在第二个计时器到 8 的时候暂停一定最大。

  1. int main() {
  2. ios_base::sync_with_stdio(false), cin.tie(0);
  3. for (cin >> _; _--;) {
  4. int n; cin >> n;
  5. cout << 9;
  6. for (int i = 1; i < n; ++i) cout << (i + 7) % 10;
  7. cout << "\n";
  8. }
  9. return 0;
  10. }

B. Hills And Valleys

山谷定义看题意,循环一次数组把 Codeforces Round #695 (Div. 2) - 图5 分别用 Codeforces Round #695 (Div. 2) - 图6Codeforces Round #695 (Div. 2) - 图7代替求算 山谷和

模拟的时候发现 ans 其实最多为 2(0,1,2),

比如在 6 1 5 4 5,这组数据把Codeforces Round #695 (Div. 2) - 图8 替换为 1 时 ans = 2.

具体代码实现

  1. using ll = long long;
  2. int _, n;
  3. vector<ll> a;
  4. bool check(int i) {
  5. if (i == 0 || i == n - 1) return false;
  6. return (a[i] > a[i + 1] && a[i] > a[i - 1]) ||
  7. (a[i] < a[i + 1] && a[i] < a[i - 1]);
  8. }
  9. int main() {
  10. ios_base::sync_with_stdio(false), cin.tie(0);
  11. for (cin >> _; _--;) {
  12. cin >> n;
  13. a = vector<ll>(n);
  14. for (auto& x : a) cin >> x;
  15. int ans = 0, cnt = 0;
  16. for (int i = 1, b, c; i < n - 1; ++i) {
  17. int t = a[i];
  18. cnt += check(i);
  19. b = c = check(i) + check(i - 1) + check(i + 1);
  20. a[i] = a[i + 1], b -= check(i - 1);
  21. a[i] = a[i - 1], c -= check(i + 1);
  22. ans = max({ans, b, c});
  23. a[i] = t;
  24. }
  25. cout << cnt - ans << "\n";
  26. }
  27. return 0;
  28. }

C. Three Bags

我们有三个背包,可以进行一种操作:

  • 移除一个背包中的一个数b,另一个背包中的一个数a变为a-b

问我们最后剩余的一个数最大可以为多少?

那么我们可以考虑最后剩余的一个数在哪个背包中,我们以在A背包中为例。

我们有三个背包,可以进行一种操作:

  • 移除一个背包中的一个数b,另一个背包中的一个数a变为a-b

问我们最后剩余的一个数最大可以为多少?

那么我们可以考虑最后剩余的一个数在哪个背包中,我们以在A背包中为例。

对于A背包中的数来说

我们将A背包的数作为b转移出去,再转移回来,负负得正,那么最后一个数可以加上A背包中所有的数的和

那么对于B和C背包来说有两种情况

  • B背包和C背包都剩下一个数,B、C背包中其他的数通过除了A之外的另一个背包先转换为 -b ,再转移到A背包中变为 b,随后在A背包中减去B、C背包中剩下的这个数,那么显然,当剩下的这两个数最小时,结果最优。
  • B背包和C背包只有一个背包剩下一个数,那么这种情况就是,其中一个背包全部作为-b转移到除了A背包之外的另一个背包,再转移到A背包中就变为了 b ,剩下的那个背包全部作为-b转移到A背包中。

我们将A背包的数作为b转移出去,再转移回来,负负得正,那么最后一个数可以加上A背包中所有的数的和

那么对于B和C背包来说有两种情况

  • B背包和C背包都剩下一个数,B、C背包中其他的数通过除了A之外的另一个背包先转换为 -b ,再转移到A背包中变为 b,随后在A背包中减去B、C背包中剩下的这个数,那么显然,当剩下的这两个数最小时,结果最优。
  • B背包和C背包只有一个背包剩下一个数,那么这种情况就是,其中一个背包全部作为-b转移到除了A背包之外的另一个背包,再转移到A背包中就变为了 b ,剩下的那个背包全部作为-b转移到A背包中。
  1. using ll = long long;
  2. int _;
  3. vector<ll> w[3];
  4. vector<int> n(3);
  5. ll cal() {
  6. ll ans = 0, s1 = 0, s2 = 0, m1 = w[1][0], m2 = w[2][0];
  7. for (int i = 0; i < n[0]; i++) ans += w[0][i];
  8. for (int i = 1; i < n[1]; i++) s1 += w[1][i];
  9. for (int i = 1; i < n[2]; i++) s2 += w[2][i];
  10. ans += max({s1 + s2 - m1 - m2, s1 + m1 - s2 - m2, s2 + m2 - s1 - m1});
  11. return ans;
  12. }
  13. int main() {
  14. ios_base::sync_with_stdio(false), cin.tie(0);
  15. for (int i = 0; i < 3; ++i) cin >> n[i];
  16. w[0].resize(n[0]), w[1].resize(n[1]), w[2].resize(n[2]);
  17. for (int i = 0; i < 3; ++i) {
  18. for (int j = 0; j < n[i]; ++j) cin >> w[i][j];
  19. sort(w[i].begin(), w[i].end());
  20. }
  21. ll ans = -1e18;
  22. // 现在考虑三种情况
  23. ans = max(ans, cal()); // A,B,C
  24. swap(w[0], w[1]), swap(n[0], n[1]);
  25. ans = max(ans, cal()); // B,A,C
  26. swap(w[0], w[2]), swap(n[0], n[2]);
  27. ans = max(ans, cal()); // C,A,B
  28. cout << ans << "\n";
  29. return 0;
  30. }

D. Sum of Paths

题意

有个机器人在 Codeforces Round #695 (Div. 2) - 图9的直线方格上面走 Codeforces Round #695 (Div. 2) - 图10 步,求所有路线下每个格子经过的次数。

思路

Codeforces Round #695 (Div. 2) - 图11:走 Codeforces Round #695 (Div. 2) - 图12 步到 Codeforces Round #695 (Div. 2) - 图13 方格的路线数。
对于每一个方格,枚举他作为中转点即可。

Codeforces Round #695 (Div. 2) - 图14%5C%20%5C%25%5C%20mod%0A#card=math&code=sum%5Bi%5D%20%3D%20%28sum%5Bi%5D%20%2B%20dp%5Bj%2Ci%5D%20%2A%20dp%5Bk-j%2Ci%5D%20%5C%25%5C%20mod%29%5C%20%5C%25%5C%20mod%0A)

  1. using ll = long long;
  2. const int MXN = 5e3 + 10;
  3. const int mod = 1e9 + 7;
  4. ll a[MXN];
  5. ll dp[MXN][MXN];
  6. ll sum[MXN];
  7. int main() {
  8. int n, k, q;
  9. cin >> n >> k >> q;
  10. for (int i = 1; i <= n; i++) {
  11. scanf("%lld", &a[i]);
  12. }
  13. for (int i = 1; i <= n; i++) dp[0][i] = 1;
  14. for (int i = 1; i <= k; i++) {
  15. dp[i][1] = dp[i - 1][2];
  16. dp[i][n] = dp[i - 1][n - 1];
  17. for (int j = 2; j < n; j++) {
  18. dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j + 1]) % mod;
  19. }
  20. }
  21. for (int i = 1; i <= n; i++) {
  22. for (int j = 0; j <= k; j++)
  23. sum[i] = (sum[i] + dp[j][i] * dp[k - j][i] % mod) % mod;
  24. }
  25. ll ans = 0;
  26. for (int i = 1; i <= n; i++) ans = (ans + sum[i] * a[i] % mod) % mod;
  27. while (q--) {
  28. ll i, x;
  29. scanf("%lld%lld", &i, &x);
  30. ans =
  31. ((ans - sum[i] * a[i] % mod + sum[i] * x % mod) % mod + mod) % mod;
  32. cout << ans << '\n';
  33. a[i] = x;
  34. }
  35. return 0;
  36. }