ABC326挑戦記(D問題)

↓問題のページ↓

AtCoder Beginner Contest 326 D - ABC Puzzle

最終的にはこの問題に敗北し、終了後に kyopro_friends氏による公式解説 の通りに実装した(これに伴い、 既存の順列全探索用ライブラリ を改良し、複数の順列に対しても全探索を実行可能とした)。

各行について、書き込まれる列が4か所以上になると第1の条件を満たし得なくなることを見出し、bit全探索を利用して3か所のbitのみが立っている状態についてのみ、各行について[A, B, C]の3文字からなる順列に応じて書き込み、書き込み完了後、3つの条件に適するかを検査し(第1の条件に関して、各行については書き込んでいる3か所が[A, B, C]の順列になっているため列に関してのみ再確認すればよい)、適切なものが見つかればそれを出力すると解けると本番中に考えたものの、探索範囲の広さを考慮すると、各行についてbitの状態数だけで

\begin{align} (2^N)^N \end{align}

通り存在し、さらに、各行に対して[A, B, C]の順列を書き込む場合の数が

\begin{align} (3!)^N \end{align}

通り存在する。Nの値は最大で5なので、探索範囲は最大で

\begin{align} (2^5)^5 \times (3!)^5 =260919263232 > 2.6 \times 10^{11} \end{align}

に及ぶためTLEし、このアルゴリズムではダメだと分かった。公式解説に書かれている通り、各行各列にAが1個ずつ配置されるようなAの書き込み方は

\begin{align} N! \end{align}

通りである(例えばNが5の時ならば、[0, 1, 2, 3, 4]の並べ替えに対し、「y番目の値がxならば、y行目のx列目にAを書き込む」と定めれば、それぞれの順列が前述のようなAの書き込み方と1対1に対応する。Nが他の値であっても同様)ため、B, Cについても書き込み方を同様に考えると、各行各列にA, B, Cがそれぞれ1度ずつ登場するような書き込み方は、最大で

\begin{align} (5!)^3 = 1728000 < 1.8 \times 10^6 \end{align}

程度にまで抑えられるため、最初の手法と同様、全マスに書き込んだのちに条件を満たすかを検査するというように処理させれば十分間に合う。

2つ以上の順列に対する全探索を実行可能なライブラリを事前に用意しておかなかった点、および赤い太字の部分を見出すことができなかった(経験不足)点が明確な原因だったと思われる。まだ手が届きそうな問題だと初見で直感的に感じたため悔いの残る結果となった。