思路分析:
经典连通块问题,考虑DFS/BFS,只要搜索外层所有的‘0’,同时将它们都进行染色,即遍历到‘0’,则将它们都变为‘*’,最后再遍历整个图对剩下‘0’进行计数即可
注意这里有个技巧:
为了避免以下情况的出现和减少DFS/BFS次数
00*00 00*00 00*00 00*00
可以主动在图的边缘加一层0,这样即可只进行一次DFS就可以搜索到所有的0
#include<iostream>
#define MAX 510
using namespace std;
int n, m;
char map[MAX][MAX];
int nextt[4][2] = { {0,1},{1,0},{0,-1},{-1,0} };
void init() {
for (int i = 0; i <= n + 1; i++) {
map[i][0] = map[i][m + 1]='0';
}
for (int i = 0; i <= m + 1; i++) {
map[0][i] = map[n + 1][i] = '0';
}
}
void dfs(int x, int y) {
if (map[x][y] == '0') {
map[x][y] = '*';
for (int i = 0; i < 4; i++) {
int tx = x + nextt[i][0];
int ty = y + nextt[i][1];
if (tx<0 || ty<0 || tx>n + 1 || ty>m + 1 || map[tx][ty] != '0') {
continue;
}
dfs(tx, ty);
}
}
}
int main()
{
int ans = 0;
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> map[i][j];
}
}
init();//在图的外层主动加0
dfs(0, 0);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
if (map[i][j] == '0') {
ans++;
}
}
}
cout << ans << endl;
return 0;
}