C++の練習を兼ねて, AtCoder Regular Contest 142 の 問題C (Tree Queries) を解いてみた.
■感想.
1. 問題Cは, 方針を絞り込めなかったので, 解説を参考に, AC版に到達できたと思う.
2. 解説上 の D[i] が 3 となるパターンについて, 細かい分岐を, すべて考慮する必要があり, 自力で, これを取り纏めることが出来なかったので, 正答まで到達出来なかったと理解した.
3. 引き続き, 時間を見つけて, 過去問の学習を進めていきたいと思う.
本家のサイト AtCoder Regular Contest 142 解説 の 各リンク を ご覧下さい.
■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 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 |
// 解き直し. // https://atcoder.jp/contests/arc142/editorial/4101 // C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; #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--) int d1[111], d2[111], d[222]; int main(){ // 1. 入力情報. int N; scanf("%d", &N); // 2. 質問(頂点 1 との 距離). repx(v, 3, N + 1){ printf("? %d %d\n", 1, v); fflush(stdout); scanf("%d", &d1[v]); } // 3. 質問(頂点 2 との 距離). repx(v, 3, N + 1){ printf("? %d %d\n", 2, v); fflush(stdout); scanf("%d", &d2[v]); } // 4. 頂点 1, 2 の 距離は? // -> 距離の和の最小値(d とする)が, 頂点 1, 2 間 の 頂点数である(d - 1)回出現するはず. // ※ 解説にある通り, この考え方は, 最小値が, 3 と異なる場合に限定されることに注意. int ans = 1; repx(v, 3, N + 1) ++d[d1[v] + d2[v]]; rep(i, 222){ if(d[i]){ // if(d[i] + 1 == i) ans = i; ans = i; break; } } // 5. d != 3. if(ans != 3){ printf("! %d\n", ans); return 0; } // 6. d = 3 かつ 出現は, 2回でない. if(d[3] != 2){ printf("! %d\n", 1); return 0; } // 7. それ以外. // 7-1. 頂点 x, y は? int x = 0, y = 0; repx(v, 3, N + 1){ if(d1[v] + d2[v] == 3){ if(!x){ x = v; continue; } if(!y){ y = v; break; } } } assert(x && y); // 7-2. 頂点 x, y の距離は? int dxy = 0; printf("? %d %d\n", x, y); fflush(stdout); scanf("%d", &dxy); // 7-3. 出力. printf("! %d\n", (dxy == 1) ? 3 : 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 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 |
※インタラクティブな問題のため, 入出力は, デバッグ時に使用したものを記載している. [入力例] 5 2 2 3 1 1 2 [出力例] ? 1 3 ? 1 4 ? 1 5 ? 2 3 ? 2 4 ? 2 5 ? 3 4 ! 1 [入力例] 7 1 2 2 2 1 2 3 1 1 2 [出力例] ? 1 3 ? 1 4 ? 1 5 ? 1 6 ? 1 7 ? 2 3 ? 2 4 ? 2 5 ? 2 6 ? 2 7 ! 1 [入力例] 7 1 2 4 3 2 2 1 1 2 3 1 [出力例] ? 1 3 ? 1 4 ? 1 5 ? 1 6 ? 1 7 ? 2 3 ? 2 4 ? 2 5 ? 2 6 ? 2 7 ? 3 4 ! 3 [入力例] 12 1 2 3 3 2 2 1 2 2 2 2 3 4 4 1 1 2 3 3 3 [出力例] ? 1 3 ? 1 4 ? 1 5 ? 1 6 ? 1 7 ? 1 8 ? 1 9 ? 1 10 ? 1 11 ? 1 12 ? 2 3 ? 2 4 ? 2 5 ? 2 6 ? 2 7 ? 2 8 ? 2 9 ? 2 10 ? 2 11 ? 2 12 ! 1 [入力例] 12 1 3 2 4 5 6 2 1 5 6 6 4 5 3 2 1 7 9 4 3 [出力例] ? 1 3 ? 1 4 ? 1 5 ? 1 6 ? 1 7 ? 1 8 ? 1 9 ? 1 10 ? 1 11 ? 1 12 ? 2 3 ? 2 4 ? 2 5 ? 2 6 ? 2 7 ? 2 8 ? 2 9 ? 2 10 ? 2 11 ? 2 12 ! 7 |
■参照サイト
AtCoder Regular Contest 142