Official
C - Puddles Editorial by en_translator
Original proposer: admin
This problem can be solved with BFS (Breadth-First Search).
Scan the cells from top-left. If the cell is not inspected yet, find the region that contains the cell, and check if the region contains an outermost cell.
Sample code (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)
Note that DSU (Disjoint Set Union) in ACL (AtCoder Library) helps simplifying the implementation.
Sample code (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;
}
posted:
last update: