2019年8月24日土曜日

ARC 006 D - アルファベット探し

ARC 006 D - アルファベット探し

chokudaiさんのツイートより。簡単な方針を思いつけなかった……

「文字を囲む正方形」の一辺の長さが常に55の倍数になることを利用する。黒マス(i,j)(i, j)が与えられたとき、(i,j)(i, j)を基点に黒マスだけを8方向にたどるBFSをして、連結成分の上下左右の境界U,D,L,RU, D, L, Rを突き止める。DU+1=5kD-U+1 = 5kとすると拡大率がkk倍とわかるので、領域[U,D]×[L,R][U, D] \times [L, R]を左上(U,L)(U, L)を基準に1/k1/k倍に縮小する。

各点に対して上の処理を行うと、図上の文字はすべて等倍になる。あとは、図上のすべての7×77\times7の正方形について、33文字×4\times 4方向 =12= 12パターンのいずれかに一致するか調べればよい。これは例えばローリングハッシュなどでできる。1 計算量はO(HW){\mathcal O}(HW)


連結成分のサイズだけ見ればよいかもというのは最初に考えたけれど、倍数では文字を1つに絞れないと思ってすぐに捨ててしまった。(実際には、文字をkk倍に拡大すると連結成分のサイズがk2k^2倍になるので、異なる文字のサイズが重なることはない。)


  1. プログラミングコンテストチャレンジブック 第2版, pp.333-335より。でも、よく考えると等倍に戻したタイミングで愚直にパターンマッチすれば十分だった。 ↩︎