公式

C - Puddles 解説 by kyopro_friends


原案:admin

この問題は BFS により解くことができます。

左上から順に各マスを見て、まだ調べていない白マスがあれば、その白マスが属する領域を求め、それが最外周のマスを含むかを確かめます。

実装例 (Python)

H, W = map(int,input().split())
S = [input() for _ in range(H)]
checked = [[False]*W for _ in range(H)]

def bfs(si, sj):
  # (si, sj) を含む白マスの領域が最外周のマスを含むか
  out = False
  q = [(si, sj)]
  checked[si][sj] = True
  for i, j in q:
    if i == 0 or i == H-1 or j == 0 or j == W-1:
      out = True
    for di, dj in [(0, 1), (0, -1), (1, 0), (-1, 0)]:
      ii = i + di
      jj = j + dj
      if 0 <= ii < H and 0 <= jj < W and S[ii][jj] == '.' and not checked[ii][jj]:
        q.append((ii, jj))
        checked[ii][jj] = True
  return out

ans = 0
for i in range(H):
  for j in range(W):
    if S[i][j] == '.' and not checked[i][j]:
      if not bfs(i, j):
        ans += 1

print(ans)

なお、ACL (AtCoder Library) の DSU を用いることで実装を簡略化することもできます。

実装例 (C++)

#include<bits/stdc++.h>
#include<atcoder/dsu>
using namespace std;
#define rep(i,l,r)for(int i=(l);i<(r);i++)
#define idx(i,j) ((i)*w+(j))

int main(){
	int h, w;
	cin >> h >> w;
	vector<string>s(h);
	rep(i, 0, h) cin >> s[i];
	
	atcoder::dsu d(h*w);
	rep(i, 0, h)rep(j, 0, w-1)if(s[i][j]=='.' && s[i][j+1]=='.'){
		d.merge(idx(i, j), idx(i, j+1));
	}
	rep(i, 0, h-1)rep(j, 0, w)if(s[i][j]=='.' && s[i+1][j]=='.'){
		d.merge(idx(i, j), idx(i+1, j));
	}
	
	set<int>s1,s2;
	rep(i, 0, h)rep(j, 0, w)if(s[i][j]=='.'){
		s1.insert(d.leader(idx(i, j)));
		if(i==0 || i==h-1 || j==0 || j==w-1){
			s2.insert(d.leader(idx(i, j)));
		}
	}
	
	cout  <<  s1.size() - s2.size() << endl;
}

投稿日時:
最終更新: