补题链接:Here

1498A. GCD Sum

题意:给定一个 gcdSum 操作:Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图1%20%3D%20gcd(762%2C7%20%2B%206%20%2B%202)%20%3D%20gcd(762%2C15)%20%3D%203#card=math&code=gcdSum%28762%29%20%3D%20gcd%28762%2C7%20%2B%206%20%2B%202%29%20%3D%20gcd%28762%2C15%29%20%3D%203)

请问要执行多少次 gcdSum 才能使结果不为 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图2

输出最后的 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图3

思路:按题意来,因为数据范围在 1e18 在执行 gcdSum 时比较快

  1. using ll = long long;
  2. ll gcd(ll x, ll y) { return y == 0 ? x : gcd(y, x % y); }
  3. ll getSum(ll n) {
  4. ll s = 0;
  5. while (n) {
  6. s += n % 10, n /= 10;
  7. }
  8. return s;
  9. }
  10. int main() {
  11. ios_base::sync_with_stdio(false), cin.tie(0);
  12. int _;
  13. for (cin >> _; _--;) {
  14. ll n;
  15. cin >> n;
  16. while (gcd(n, getSum(n)) == 1) n++;
  17. cout << n << "\n";
  18. }
  19. return 0;
  20. }

1498B. Box Fitting

题意:在一个被限定了宽度的盒子中给一些长度为 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图4 高度为 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图5 的长方块,请问怎么排放才能使最终高度==最小==

思路:先利用 map 存储各个长度的值,然后二分找到在该行中最大的一块然后填充。

这里建议看代码理解

  1. int main() {
  2. ios_base::sync_with_stdio(false), cin.tie(0);
  3. int _;
  4. for (cin >> _; _--;) {
  5. int n, w;
  6. cin >> n >> w;
  7. map<int, int> mp;
  8. for (int i = 0, x; i < n; ++i) {
  9. cin >> x;
  10. mp[x]++;
  11. }
  12. int ans = 1, cur = w;
  13. while (mp.size()) {
  14. if (mp.begin()->first > cur) {
  15. ++ans, cur = w;
  16. }
  17. auto it = prev(mp.upper_bound(cur));
  18. assert(it->first <= cur);
  19. cur -= it->first;
  20. if (--(it->second) == 0) mp.erase(it);
  21. }
  22. cout << ans << "\n";
  23. }
  24. return 0;
  25. }

1498C. Planar Reflections

DP优化 + 模拟

题意:给定一个可以穿越墙体的微观粒子(寿命为 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图6),但是每穿越一次墙体会产生一个反向寿命为 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图7 的粒子。

请问最终共有多少个粒子?

思路:模拟变化过程,然后开DP数组存储已经计算过的即可,写的时候要注意细节,比如什么时候 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图8 或者 Codeforces Round #711 (Div. 2) CodeCraft-21 A~C 个人题解 - 图9 方向变化

  1. const int mod = 1e9 + 7;
  2. int n, k;
  3. int dp[1010][1010][2];
  4. int solve(int cur, int k, int dir) {
  5. if (k == 1) return 1;
  6. // 非 -1 说明已经计算过了
  7. if (dp[cur][k][dir] != -1) return dp[cur][k][dir];
  8. int ans = 2; // 本身和穿过墙的复制体
  9. if (dir == 1) {
  10. if (cur < n) ans += solve(cur + 1, k, dir) - 1;
  11. ans %= mod;
  12. if (cur > 1) ans += solve(cur - 1, k - 1, 1 - dir) - 1;
  13. ans %= mod;
  14. dp[cur][k][dir] = ans;
  15. } else {
  16. if (cur > 1) ans += solve(cur - 1, k, dir) - 1;
  17. ans %= mod;
  18. if (cur < n) ans += solve(cur + 1, k - 1, 1 - dir) - 1;
  19. ans %= mod;
  20. dp[cur][k][dir] = ans;
  21. }
  22. return ans;
  23. }
  24. int main() {
  25. ios_base::sync_with_stdio(false), cin.tie(0);
  26. int _;
  27. for (cin >> _; _--;) {
  28. cin >> n >> k;
  29. memset(dp, -1, sizeof dp);
  30. cout << solve(1, k, 1) << '\n';
  31. }
  32. return 0;
  33. }

在学习高榜大佬的代码时候发现的一种解法,Orz…

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int mod = 1e9 + 7;
  4. int X[1001], Y[1001], n, k, K, R, val;
  5. signed main() {
  6. for (cin >> n; cin >> n >> k;) {
  7. for (R = 0; R <= n; R++) X[R] = Y[R] = 0;
  8. for (K = 2; K <= k; K++) {
  9. for (R = n; R >= 0; R--) X[R] = (R + Y[n - R]) % mod;
  10. val = 0;
  11. for (R = n - 1; R >= 0; R--) Y[R] = (val += X[R]) %= mod;
  12. }
  13. cout << (1 + X[n]) % mod << ' ';
  14. }
  15. }