問題概要
高さ $H$, 幅 $W$ のグリッド状の盤面がある.グリッドの各セルは '.' または '#' である.
縦に 2 つ隣接する '.' の箇所と,横に 2 つ隣接する '.' の箇所の数の和を求めよ.
制約
- $2 \leq H, W \leq 100$
解法
答えの総数は $O( HW )$ 個です.制約のサイズから,$\Theta( HW )$ 時間かけて数えても間に合います.よって,配置の左上になるセルと縦/横をすべて試して数えることができます.
具体的には,セル $( i, j )$ をすべて舐めて,'.' であるようなセル $( i, j )$ に対して,セル $( i + 1, j )$ が存在してそこが '.' である場合(縦の配置)と,セル $( i, j + 1 )$ が存在してそこが '.' である場合(横の配置)の発生回数を数えればよいです.
コード
int main() { IN( int, H, W ); VS board( H ); cin >> board; const auto ok = [&]( const int y, const int x ) { return 0 <= y && y < H && 0 <= x && x < W && board[y][x] == '.'; }; int res = 0; REP( i, H ) { REP( j, W ) { res += ok( i, j ) && ok( i + 1, j ); res += ok( i, j ) && ok( i, j + 1 ); } } cout << res << endl; return 0; }
main = do [ h, _ ] <- readInts board <- replicateM h getLine let trans = transpose board print $ sum ( map solve board ) + sum ( map solve trans ) solve [_] = 0 solve (c1:c2:rest) | c1 == '.' && c2 == '.' = 1 + solve (c2:rest) | otherwise = solve (c2:rest)