C++の練習を兼ねて, AtCoder Beginner Contest 224 の 問題C (Triangle?) ~ 問題D (8 Puzzle on Graph) を解いてみた.
■感想.
1. 問題Dは, 方針が見えなかったので, 解説を参考に提出して, ようやく, AC版に到達出来た.
2. 幅優先探索(応用版, 連想配列の利用)の復習が出来たので, 非常に良かったと思う.
3. 引き続き, 時間を見つけて, 過去問の学習を進めていきたいと思う.
本家のサイト AtCoder Beginner Contest 224 解説 の 各リンク を ご覧下さい.
■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 x[303], y[303]; int main(){ // 1. 入力情報. int N; scanf("%d", &N); rep(i, N) scanf("%lld %lld", &x[i], &y[i]); // 2. 三角形の面積が正となるものは? int ans = 0; rep(i, N){ repx(j, i + 1, N){ repx(k, j + 1, N){ // 点(x[i], y[i]) を 基準として考える. LL dx1 = x[j] - x[i], dy1 = y[j] - y[i]; LL dx2 = x[k] - x[i], dy2 = y[k] - y[i]; // 三角形の面積の二倍. LL s = abs(dx1 * dy2 - dy1 * dx2); // カウント. if(s) ans++; } } } // 3. 出力. 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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
[入力例] 4 0 1 1 3 1 1 -1 -1 [出力例] 3 ※AtCoderテストケースより [入力例] 20 224 433 987654321 987654321 2 0 6 4 314159265 358979323 0 0 -123456789 123456789 -1000000000 1000000000 124 233 9 -6 -4 0 9 5 -7 3 333333333 -333333333 -9 -1 7 -10 -1 5 324 633 1000000000 -1000000000 20 0 [出力例] 1124 ※AtCoderテストケースより [入力例] 25 524 378 4912 11687 1572 1134 1683 7524 11403 2790 2096 1512 4486 4715 3198 1800 1531 2059 2620 1890 10956 8787 5357 7672 12062 1210 14608 11716 3144 2268 3668 2646 4192 3024 18260 14645 4716 3402 1822 18104 5372 11052 2733 27156 5240 3780 3644 36208 5466 54312 [出力例] 2211 |
■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 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 |
// 解き直し. // https://atcoder.jp/contests/abc224/editorial/2813 // C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; using vi = vector<int>; #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 #define all(x) x.begin(), x.end() int g[10][10], p[10], q[10]; int main(){ // 1. 入力情報. int M; scanf("%d", &M); rep(i, M){ int a, b; scanf("%d %d", &a, &b); a--; b--; g[a][b] = 1; g[b][a] = 1; } // 2. 初期状態. rep(i, 10) q[i] = 9; rep(i, 8){ scanf("%d", &p[i]); q[p[i]] = i + 1; } string s = ""; repx(i, 1, 10) s.pb(q[i] + '0'); // printf("%s\n", s.c_str()); // 3. 駒の配置(全通り). map<string, int> m; vi z(9); iota(all(z), 1); do{ // 3-1. 駒の配置を作成. string t = ""; rep(i, 9) t.pb(z[i] + '0'); // 3-2. 保存. m[t] = -1; // printf("%s\n", t.c_str()); }while(next_permutation(all(z))); // 4. 初期状態 から コマの配置までの距離を計算. // https://ja.wikipedia.org/wiki/幅優先探索 auto bfs = [&](string s, map<string, int> &d){ // 4-1. 空のキュー. queue<string> q; // 4-2. 開始地点の距離. d[s] = 0; // 4-3. 探索地点 s をキュー q に追加. q.push(s); while(!q.empty()){ // 4-4. キューから取り出す. string u = q.front(); q.pop(); // 4-5. グラフの辺を全探索. rep(i, 9){ repx(j, i + 1, 9){ // 辺(i, j) が存在するか? if(g[i][j]){ // s[i] = 9 or s[j] = 9 の 場合. if(u[i] == '9' || u[j] == '9'){ // コピー作成. string v = u; // s[i], s[j] を 入れ替え. swap(v[i], v[j]); // 未訪問ならば追加. if(m[v] == -1){ m[v] = m[u] + 1; q.push(v); } } } } } } return; }; bfs(s, m); // 5. 出力. printf("%d\n", m["123456789"]); 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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
[入力例] 5 1 2 1 3 1 9 2 9 3 9 3 9 2 4 5 6 7 8 [出力例] 5 ※AtCoderテストケースより [入力例] 5 1 2 1 3 1 9 2 9 3 9 1 2 3 4 5 6 7 8 [出力例] 0 ※AtCoderテストケースより [入力例] 12 8 5 9 6 4 5 4 1 2 5 8 9 2 1 3 6 8 7 6 5 7 4 2 3 1 2 3 4 5 6 8 7 [出力例] -1 ※AtCoderテストケースより [入力例] 12 6 5 5 4 4 1 4 7 8 5 2 1 2 5 6 9 3 6 9 8 8 7 3 2 2 3 4 6 1 9 7 8 [出力例] 16 ※AtCoderテストケースより [入力例] 0 1 6 4 8 5 2 3 7 [出力例] -1 [入力例] 11 1 9 1 6 2 6 2 4 4 9 6 9 3 6 3 9 5 9 5 7 7 9 6 4 2 1 7 3 5 8 [出力例] 11 [入力例] 30 4 7 1 9 2 5 1 5 3 5 6 8 2 4 3 9 4 9 3 7 5 6 5 9 1 2 3 6 5 7 7 8 2 3 2 9 3 8 7 9 2 6 2 8 1 4 2 7 3 4 4 6 4 8 1 8 1 3 4 5 3 2 6 7 5 1 4 8 [出力例] 7 [入力例] 36 1 2 1 3 1 4 1 5 1 6 1 7 1 8 1 9 2 3 2 4 2 5 2 6 2 7 2 8 2 9 3 4 3 5 3 6 3 7 3 8 3 9 4 5 4 6 4 7 4 8 4 9 5 6 5 7 5 8 5 9 6 7 6 8 6 9 7 8 7 9 8 9 8 5 7 3 6 2 4 1 [出力例] 11 |
■参照サイト
AtCoder Beginner Contest 224