競技プログラミング用 知識集積所

ABC424D - 2x2 Erasing 2

最終更新:

sport_programming

- view
管理者のみ編集可


問題


必要知識

B以下レベルの内容は省略

考え方

サイズが最大7x7と小さいが、最大100問出されるので、1問あたり2x10^6回くらいの計算で処理する必要がある。
単純なbit全探索とかでやると、端のマスを候補から除外するとしても間に合わない。

そこで、貪欲法※でうまくいかないか考えてみる。
左上から右方向にチェックしていくとして、黒い2x2を見つけたら、そのうちどれかを白くする。
このとき、左上を塗るのは左下の下位互換、右上を塗るのは右下の下位互換である。
しかし、左下が右下の下位互換かと言えばそうでもない。
反例
□■■
■■■
■■□
そこで、2択だけ消すことにして、残る2択は深さ優先探索※で処理しながら最小値を探す。
この際、「左下を白にする→木を彫り進める→戻ってきたら左下を黒に戻す→右下を白にする→木を彫り進める→戻ってきたら右下を黒に戻す」という形にすると、計算を毎回1からやらなくて済むので高速化できる。

問題は計算量の見積もり。
特に7x7の場合に2x10^6回で収まるかの判断が重要。

まず、この方針では1段目を自分で塗ることは絶対にない。
「2段目と3段目」「4段目と5段目」「6段目と7段目」をそれぞれペアにして考える。
同じ縦列のマスをペアにして考えると、上下両方を自分で塗ることは絶対にない。
さらに、7列全て上下どちらかを塗るということにも絶対にならない。
ということは、各2x7の長方形内で、自分で塗るのは最大で6マスである。
つまり全体で最大18マスまでしか自分で塗らない。
木の高さが最大18で、各所で2択にしかならないのだから、探索は2^18=262144通り以下で済む。
定数倍次第で少し怖いが、実際は18マスも自分で塗るパターンはほぼ起こらないので、よほど下手な実装をしなければ十分間に合う。

解答例


注意点

解法によっては幅や高さが2の場合がコーナーケースになるので注意。

端の部分を白く塗る候補から外す解法だと、幅2の場合や高さ2の場合に黒マス2x2がどうやっても消せなくなる。
3マス以上ない場合はどちらかの列を候補に残しておくこと。
(そういう解法で間に合うかものがあるかどうかは不明)

別解

ウィキ募集バナー