C++の練習を兼ねて, AtCoder Beginner Contest 309 の 問題C (Medicine) ~ 問題E (Family and Insurance) を解いてみた.
■感想.
1. 問題C ~ E は, 方針を絞り込めたので, AC版に到達できたと思う.
2. 個人的には, 幅優先探索, 深さ優先探索の訓練を積めたので, 非常に良かったと思う.
3. 引き続き, 時間を見つけて, 過去問の学習を進めていきたいと思う.
本家のサイト AtCoder Beginner Contest 309 解説 の 各リンク を ご覧下さい.
■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--) #define a first #define b second int main(){ // 1. 入力情報. int N; LL K; scanf("%d %lld", &N, &K); map<LL, LL> m; rep(i, N){ LL a, b; scanf("%lld %lld", &a, &b); m[1] += b; m[a + 1] -= b; } // 2. K 錠以下となる日は? LL ans = 0, bef = 0; for(auto &x : m){ if(bef + x.b <= K){ ans = x.a; break; } bef += x.b; } // 3. 出力. printf("%lld\n", ans); 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 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 |
[入力例] 4 8 6 3 2 5 1 9 4 2 [出力例] 3 ※AtCoderテストケースより [入力例] 4 100 6 3 2 5 1 9 4 2 [出力例] 1 ※AtCoderテストケースより [入力例] 15 158260522 877914575 2436426 24979445 61648772 623690081 33933447 476190629 62703497 211047202 71407775 628894325 31963982 822804784 50968417 430302156 82631932 161735902 80895728 923078537 7723857 189330739 10286918 802329211 4539679 303238506 17063340 492686568 73361868 125660016 50287940 [出力例] 492686569 ※AtCoderテストケースより [入力例] 20 50 35 89 113 68 12 91 47 39 50 102 31 44 113 70 45 66 100 93 80 68 51 93 105 17 74 99 112 68 47 106 119 121 86 36 95 13 76 48 17 10 [出力例] 120 [入力例] 30 123456789 7243344 39645001 110611721 58764066 54943571 7858259 27652310 45631404 108885402 58254068 63309952 54581014 14961992 64159015 50683657 90394950 114601656 67985265 27910507 21684920 14643649 75065657 81812380 68477230 99446454 110995892 28245926 89882812 19853288 72407860 9336074 108313969 56279010 58943019 32548337 96665548 90304960 21889493 32324555 100548176 50649146 67321897 14707156 3434551 119127221 33695514 70909013 99071221 15471945 54145916 110898063 49158872 15649382 75510226 21230601 28253500 71654589 9111419 120392263 8725587 [出力例] 110898064 |
■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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
// C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; using vi = vector<int>; using vvi = vector<vi>; #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--) #define pb push_back int main(){ // 1. 入力情報. int N1, N2, M; scanf("%d %d %d", &N1, &N2, &M); int N = N1 + N2; vvi G(N); rep(i, M){ int a, b; scanf("%d %d", &a, &b); --a; --b; G[a].pb(b); G[b].pb(a); } // 2. bfs. // https://ja.wikipedia.org/wiki/幅優先探索 auto bfs = [&](vvi &G, int s, int* d){ // 空のキュー. queue<int> q; // 探索地点 s をキュー q に追加. q.push(s); while(!q.empty()){ // キューから取り出す. int u = q.front(); q.pop(); // 隣接頂点をチェック. for(auto &v : G[u]) if(!d[v] && v != s) d[v] = d[u] + 1, q.push(v); } }; int d1[N], d2[N]; rep(i, N) d1[i] = d2[i] = 0; bfs(G, 0, d1); bfs(G, N - 1, d2); // 3. 最大値は? int ans1 = 0, ans2 = 0; rep(i, N) ans1 = max(ans1, d1[i]); rep(i, N) ans2 = max(ans2, d2[i]); // 4. 出力. printf("%d\n", ans1 + ans2 + 1); 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 |
[入力例] 3 4 6 1 2 2 3 4 5 4 6 1 3 6 7 [出力例] 5 ※AtCoderテストケースより [入力例] 7 5 20 10 11 4 5 10 12 1 2 1 5 5 6 2 4 3 5 9 10 2 5 1 4 11 12 9 12 8 9 5 7 3 7 3 6 3 4 8 12 9 11 [出力例] 4 ※AtCoderテストケースより [入力例] 5 7 10 1 2 2 5 3 4 4 5 6 7 6 8 8 10 9 10 11 9 11 12 [出力例] 11 [入力例] 6 9 13 2 1 3 1 3 4 5 3 4 6 8 7 7 10 10 9 9 14 13 14 11 10 12 11 15 11 [出力例] 9 |
■C++版プログラム(問題E/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 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 |
// C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; using vi = vector<int>; using vvi = vector<vi>; #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--) #define pb push_back int memo[303030], insurance[303030]; int main(){ // 1. 入力情報. int N, M; scanf("%d %d", &N, &M); vvi G(N); repx(i, 1, N){ int p; scanf("%d", &p); --p; G[i].pb(p); G[p].pb(i); } int y[N]; rep(i, N) y[i] = -1; rep(i, M){ int a, b; scanf("%d %d", &a, &b); --a; y[a] = max(y[a], b); } // 2. dfs. // https://ja.wikipedia.org/wiki/深さ優先探索 function<void(vvi&, int, int, int)> dfs = [&](vvi &G, int cur, int bef, int d) { // 終了条件. if(memo[cur]) return; // 訪問済みフラグ. memo[cur] = 1; // 補償対象者か? if(d >= 0) ++insurance[cur]; // 隣接頂点. for(auto &nex : G[cur]){ if(nex == bef) continue; dfs(G, nex, cur, max(d - 1, y[nex])); } }; dfs(G, 0, -1, y[0]); /* rep(i, N) printf("%d ", insurance[i]); puts(""); */ // 3. 集計. int ans = 0; rep(i, N) ans += (insurance[i] > 0); // 4. 出力. printf("%d\n", ans); 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 |
[入力例] 7 3 1 2 1 3 3 3 1 1 1 2 4 3 [出力例] 4 ※AtCoderテストケースより [入力例] 10 10 1 1 3 1 2 3 3 5 7 2 1 5 1 4 3 6 3 2 1 7 3 9 2 1 2 6 2 8 1 [出力例] 10 ※AtCoderテストケースより [入力例] 15 5 1 2 5 1 5 6 6 4 4 8 8 3 13 14 1 1 4 1 12 1 8 2 14 1 [出力例] 11 [入力例] 25 7 1 2 2 1 1 6 6 5 4 4 7 7 8 8 3 3 11 11 19 19 12 22 22 24 3 1 16 1 19 1 18 2 22 2 14 1 12 1 [出力例] 13 |
■参照サイト
デンソークリエイトプログラミングコンテスト2023(AtCoder Beginner Contest 309)