A | B | C | D | E | F | |
問題文 | ■ | ■ | ■ | ■ | ■ | ■ |
自分の提出 | ■ | ■ | ■ | ■ | ■ | ■ |
結果 | AC | AC | AC | AC | AC | AC |
全体感想
36分6完1ペナで、64位でした。
わりと良い出来だと思ったのですが、上位陣はえぇ。
特に、簡単回という印象はないのですが、最速タイムで見てもAC人数で見ても人数が多いですね。すごい。強いて言うなら、Dはいつにも増して基本問題でした。
問題D – Maze Master
基本の幅優先探索です。単一始点最短経路問題を全点について解きます。
関連問題:ABC 007-C 幅優先探索
1回の移動コストが 0 または 1 である場合には、優先度付きキュー(heapq)を使わずとも deque で距離順を維持できることに注意しましょう。
また私は、グリッドグラフは、基本的には番兵を入れて、さらに1次元化して扱っています。扱う量の次元を減らせるので好んでいますが、好みの違いレベルだと思います。
$H,W$ を問題文の値よりも $2$ 増やして、最初と最後の行に壁を追加。各行の前後に壁を追加です。移動は、座標を $\pm 1, \pm W$ のいずれかだけ変化させます。
番兵を入れる利点としては、配列外参照が自動的に防げるからです。常に壁でないところから出発するようにすれば、
・if (移動先がグリッド内) and (移動先が壁でない)
としなければいけないところが
・if ( 移動先が壁でない )
だけで済みます。コードが簡略化されるだけでなく、評価する条件が減る分、パフォーマンスの地味な定数倍改善です。(マス目の個数は増えますが、これは、$H$ が $H+2$ になったりするだけなので、十分大きな $H,W$ に対しては定数倍より影響が少ないです)。
問題E – Max-Min Sums
問題F – Enclose All
『獲得金メダル! 国際数学オリンピック メダリストが教える解き方と技』
で丁寧に扱われています(せんでん)。
$3$ 点 $z_1,z_2,z_3$ の外心を求めます。平行移動します。つまり $a = z_2 – z_1$, $b = z_3 – z_1$ として、$0, a, b$ の外心を求めればよいです。方程式 $|z|^2 = |z-a|^2 = |z-b|^2$ を解けばよいです。展開して $|z|^2$ を引くと、
\[\begin{align*} \overline{a}z+a\overline{z} &= a\overline{a},\\ \overline{b}z+b\overline{z} &= b\overline{b}\end{align*}\]
を解けばよいです。$z, \overline{z}$ に関する連立1次方程式とみると、$z = \frac{ab(\overline{a}-\overline{b})}{b\overline{a}-a\overline{b}}$ が分かります。
最後に、平行移動した分を戻すことを忘れないようにしましょう(1ペナ)。
なお、複素数は、Python では $z = x + y * 1j$ の要領で定義して扱うことができます。虚数単位は $j$ です。
※ 最小包含円という有名問題で、さらに効率よく計算できるようです。