Music. Technology. Pixels. A cup of tea
一瞬約数判断を素因数分解か結果の埋め込みかで解こうとしてしまった.editorialにもあるががの約数かどうかはがで割り切れるか,すなわちかで見ることができる. 解答例
配列で個数をカウントするよくある手法. 解答例
種類の出現回数,すなわちを好きな食べ物としている人数をに記録しておけば,種類が全員に好かれているかはか否かで判断可能.記録するためにはが見つかるたびに+=をすればよい.
直観的に通してしまった.恐らくCodeforcesで類題を見たことがある.解法としてはを取ればよい. 解答例
editorialが親切なのであまり書くことがないが,答えの候補にgcdがあることの雑な説明:攻撃による体力変動から最後のモンスターの体力はの形になるはず.これは整数を上手に決めて作れる数の範囲内であるから,その粒度は最も細かくてである(実現可能性を扨措いて).これにより求める答えがgcd以上であることが言えたから,あとはeditorial通りユークリッドの互除法に気付けばgcdが実際に構築可能かつ最小と分かり,答えとなる.
ユークリッドの互除法になることについてもちょっと書いておきたくなった:体力について大小関係が逆転するまで と遷移させると確かに.
をだと思い込み,コードテストで1200ms(C++で400ms)で動くのに何で提出するとTLEなんだろうとか言っていた. 解答例
最初に浮かんだ方針は「桁目まで使って残りマッチ数がのときに作れる最大の整数(int64
を超えるため文字列で管理)」[1].
更新は
である(は使える数字,はそのコスト,「」は文字列連結)が,TLEする[2].
ここで桁数が要らない気がしてくる:例えば使う数字として(コスト)と(コスト)を考えてもかなり隙間が空くことになるし,「残りマッチ数がのときに作れる整数」を考えるには不要な情報である.そこでさらに状態を纏めて「残りマッチ数がのときに作れる最大の整数」とし,を順に埋めていくことを考えると,遷移は
となる.これなら間に合う.
なお文字列で表した数字のmaxは,単にPervasives.max
では分からない(ほかの言語でも多分そう):maxで使われている文字列比較は辞書順による比較なので111
と2
では後者のほうが大きくなってしまう.したがって(1)桁数の大きさ,(2)先頭から見て初めて相違となる数字の大きさ,の順に決める必要があり,これは自前で実装することになる.
実装に際してPervasives.compare
の結果が何を表すかよく覚えていなかったのでメモ:第一引数が大きい(+1)
か小さい(-1)
か等しい(0)
かで覚えるのがよいだろうか.
editorialでは桁数を先にdpで求めてから数字を復元している.正直なところこの問題ではこの方針を採る利点があまり分からない.いちいち文字列を構築したくないときには良いのかもしれない.
因みに「優先度が最高のものを貪欲に並べて桁数最大にする → 余りを調整」みたいな方針も最初の実装中に考えていた.でも2つ以上の数字を使ったりもするので結局似たようなdpをすることになりそう?