C++の練習を兼ねて, AtCoder Beginner Contest 220 の 問題C (Long Sequence) ~ 問題D (FG operation) を解いてみた.
■感想.
1. 問題D は, 動的計画法の更新式を抽出できたので, AC版に到達できたと思う.
2. 苦手な動的計画法の訓練を積めたので, 非常に良かったと思う.
3. 引き続き, 時間を見つけて, 過去問の学習を進めていきたいと思う.
本家のサイト AtCoder Beginner Contest 220 解説 の 各リンク を ご覧下さい.
■C++版プログラム(問題C/AC版).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; using LL = long long; #define repex(i, a, b, c) for(int i = a; i < b; i += c) #define repx(i, a, b) repex(i, a, b, 1) #define rep(i, n) repx(i, 0, n) #define repr(i, a, b) for(int i = a; i >= b; i--) LL a[101010], aCum[101010]; int main(){ // 1. 入力情報. int N; LL X; scanf("%d", &N); rep(i, N) scanf("%lld", &a[i]); scanf("%lld", &X); // 2. 累積和. rep(i, N) aCum[i + 1] = aCum[i] + a[i]; // 3. 商, 余りは? LL q = X / aCum[N]; LL r = X % aCum[N]; // 4. 余りを超える位置は? int at = -1; rep(i, N + 1){ if(aCum[i] > r){ at = i; break; } } // 5. 出力. printf("%lld\n", q * N + (LL)at); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
[入力例] 3 3 5 2 26 [出力例] 8 ※AtCoderテストケースより [入力例] 4 12 34 56 78 1000 [出力例] 23 ※AtCoderテストケースより [入力例] 10 5 1 9 11 6 5 1 2 12 7 2021 [出力例] 344 [入力例] 20 34 121 72 71 95 78 78 32 86 109 73 39 81 23 68 78 54 98 76 33 20210927 [出力例] 288934 [入力例] 50 554 261 807 477 51 847 575 1186 901 415 520 381 622 1115 438 1010 625 1234 732 415 814 1193 1033 112 1125 1028 984 1113 928 535 656 12 287 874 1196 94 1089 986 177 988 812 246 414 1097 134 152 19 942 1096 1165 1000000000000000000 [出力例] 1450662952969509 |
■C++版プログラム(問題D/AC版).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
// C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; using LL = long long; #define repex(i, a, b, c) for(int i = a; i < b; i += c) #define repx(i, a, b) repex(i, a, b, 1) #define rep(i, n) repx(i, 0, n) #define repr(i, a, b) for(int i = a; i >= b; i--) const LL MOD = 998244353; LL dp[101010][10]; int a[101010]; int main(){ // 1. 入力情報. int N; scanf("%d", &N); rep(i, N) scanf("%d", &a[i]); // 2. dp更新. dp[0][a[0]] = 1; rep(i, N - 1){ rep(j, 10){ // 操作 F. int f = (j + a[i + 1]) % 10; dp[i + 1][f] += dp[i][j]; dp[i + 1][f] %= MOD; // 操作 G. int g = (j * a[i + 1]) % 10; dp[i + 1][g] += dp[i][j]; dp[i + 1][g] %= MOD; } } // 3. 出力. rep(i, 10) printf("%lld\n", dp[N - 1][i]); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
[入力例] 3 2 7 6 [出力例] 1 0 0 0 2 1 0 0 0 0 ※AtCoderテストケースより [入力例] 5 0 1 2 3 4 [出力例] 6 0 1 1 4 0 1 1 0 2 ※AtCoderテストケースより [入力例] 10 1 4 1 4 2 1 3 5 6 2 [出力例] 108 2 174 38 38 4 46 10 82 10 [入力例] 33 3 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6 2 6 4 3 3 8 3 2 7 9 5 0 [出力例] 795218227 107345812 107305502 107505240 107361985 644232897 107505240 107305502 107345812 107352373 [入力例] 200 1 0 9 1 6 0 2 0 8 3 0 6 3 5 1 8 0 5 1 9 8 7 7 9 0 3 0 6 1 9 7 5 0 3 4 1 1 0 0 4 4 7 1 1 1 2 7 3 4 4 8 2 3 3 8 2 9 8 0 0 1 4 2 5 4 7 3 4 1 9 4 9 1 8 5 3 6 0 0 4 6 2 4 7 5 1 0 1 3 9 4 9 6 5 8 6 9 8 1 8 0 2 9 8 5 6 1 1 0 3 2 7 0 4 4 2 5 0 0 1 4 2 9 8 5 2 8 7 3 6 1 8 1 3 0 6 4 4 2 1 4 5 1 3 8 5 9 8 8 9 9 2 1 4 3 3 3 4 4 1 7 3 7 1 4 0 7 3 5 3 6 2 9 2 8 8 2 2 1 9 7 6 8 0 3 7 7 3 6 5 4 8 7 6 7 7 8 8 8 6 [出力例] 905413840 17605008 307786178 847871598 26241917 17716361 76727260 463602346 95789053 727441864 |
■参照サイト
AtCoder Beginner Contest 220