AtCoder Beginner Contest #120
A. Favorite Sound
お金を消費して聴ける回数は切り捨てで回.聴く回数はこれと聴きたい回数とのうち小さいほう. 解答例
やはり切り捨てか否かは今でもちょっと迷う.今回のようなでは切り捨て,なら切り上げ,の場合はが整数かどうかの場合分けを加える感じだろうか.このようにを求める形に書き換えて考えると納得しやすいと個人的には思う.今回はなので切り捨て.
B. K-th Common Divisor
約数を調べても良さそうだが,が小さいのでループでよい.約数の存在範囲はであるから(これが浮かばなくてもからループを回せばよい),この範囲の数を降順に調べ,約数かどうかを判定していけばよい. 解答例
editorialにある「の公約数はの約数」は言われてみれば当たり前ではあるが意外と盲点だったので覚えておきたい.
C. Unification
無くなるまで消すような解法では間に合わなそうなので別角度から.最終状態を先に考えると,異なる数字が隣り合う箇所が無くなっているはず.すなわち残った数字は一種類だけのはず.従って少ないほうの数字がすべて消費されることが分かるが,このとき操作の条件から多いほうの数字も同数だけ消費される.勿論これ以上は消せないから,よって答えはの数の数. 解答例
こういう系の問題は苦手だが今回は瞬間的に↑が浮かんで良かった.実装が思いっきり破壊的だがこれはString
にfold
がなく非破壊的に書こうとすると面倒なため.まあArray.init
を使えばよかったのだけど.
D. Decayed Bridges
UnionFindライブラリにバグを埋め込んでいて少々困った:連結成分のサイズを返すべきところで代表元を返していた. 解答例
ある橋が無くなったときに生じる不便さは,「そのときにそれぞれの島が属する連結成分のサイズの積(連結成分が等しいときは)」である(連結成分同士の直積を考えるとよい).連結関連のあれこれはUnionFindで求めたくなるが,素のUnionFindでは橋の消滅に対応できない.実際に橋を壊すたびに連結成分の個数およびサイズは変化するから,そのままでは「橋を落としたときの連結成分のサイズ」を得るのは厳しそう.
ここで逆に最後の橋から順に橋を架けていくことを考えると,これならそのときの連結成分のサイズがそのままUnionFindで分かる.よってこの順番に積を求めていく.この値はその橋を架けることによって減る不便さ,裏を返せば橋を壊すことで発生する不便さである.求める値は番目までの橋をすべて壊したときの合計であるから,先の値をまた逆順に並び替えて累積させたものが答えとなる.