パナソニックプログラミングコンテスト(AtCoder Beginner Contest 186)参加記(~E問題)
100-200-300(1)-400-500-0で1ペナ5完1500点。
B - Blocks on Grid
ブロックに対してできる操作は、「ブロックを取り除く」のみである。この操作でブロックの個数が増えることはないので、操作後のブロックの個数はすべてのマスの中で一番少ないものに合わせる必要がある。
よって、マス目を全探索してブロックの個数の最小値を保持し、各マスにあるブロックの個数との差の総和を求めればよい。
計算量は、。
C - Unlucky 7
公式解説とは違うオーバーキル気味な方法で通した。
前計算として、「進数で表すとを含む」「進数で表すとを含む」数を列挙する。再帰関数で幅優先探索を実装し、が含まれる数のみを配列に放り込んでsort->unique->eraseすると、を含む数が昇順で並ぶ。あとは与えられた以下の数の個数を、配列の二分探索を用いて求めればよい。
計算量ってどれくらいなんだろう?幅優先探索で生成されるノードの数は進数の場合個なんだけど、これを数式でを使ってきれいに書けないな…。くらいということにしておく。
[追記]ソートしているので計算量はでした。ソートの存在忘れがち
A進数をB進数に変換する関数を暇なときに組もうと思った(暇なときにやる気が起きるはずがないので永遠に実装されない)。
D - Sum of difference
絶対値記号が邪魔なので配列をソートして考える。さらに引かれる数と引く数ごとにわけて考えると、それぞれの整数が足される回数は配列の添え字番号に依存していることがわかる。
具体的には、
が答え。
計算量は、。
E - Throne
拡張ユークリッドの互除法で解いた。
玉座を番目の椅子と考えると、
を満たす最小のが解となる。少し変形すると
となる。これは、拡張ユークリッドの互除法を用いて
を満たすを求める問題に落とせる。
計算量は、。
F - Rook on Grid
解けなかった。縦→横と動くパターンと、横→縦と動くパターンで分けて考えた後重複するマスを引く方針で考えたが、上手くいかずタイムアップ。もっと形式的にできるっぽい。
感想
C問題とE問題を解くのが遅かった。特にC問題は単純実装でも通る問題だったので、オーバーキル解法をゴリゴリ実装する前にもっと簡単に記述できる解法はないか考えるべきだった。