题目描述
小明和他的朋友周末相约去召唤师峡谷踏青。他们发现召唤师峡谷的地图是由一块一块格子组成的,有的格子上是草丛,有的是空地。草丛通过上下左右 4 个方向扩展其他草丛形成一片草地,任何一片草地中的格子都是草丛,并且所有格子之间都能通过上下左右连通。如果用’#‘代表草丛,’.'代表空地,下面的峡谷中有 2 片草地。
##..
..##
处在同一个草地的 2 个人可以相互看到,空地看不到草地里面的人。他们发现有一个朋友不见了,现在需要分头去找,每个人负责一片草地,小明想知道他们至少需要多少人。
输入描述
第一行输入 n, m (1≤n,m≤100) 表示峡谷大小
接下来输入 n 行字符串表示峡谷的地形
输出描述
输出至少需要多少人
样例
样例输入
5 6
.#....
..#...
..#..#
...##.
.#....
样例输出
5
思路
将每一片草地视为一个连通块,那么本题的目的就是查找连通块的个数,那么采用DFS即可。
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n, m;
int ans = 0; // 记录连通块个数
// 四个方向
int dx[4] = {0, 0, -1, 1};
int dy[4] = {1, -1, 0, 0};
char a[106][106];
bool vis[106][106]; // 是否已访问
void dfs(int x, int y)
{
int nx, ny;
// 遍历四个方向
for (int i = 0; i < 4; i++)
{
nx = x + dx[i];
ny = y + dy[i];
if (vis[nx][ny] == 0)
{
vis[nx][ny] = 1;
if (a[nx][ny] == '#')
dfs(nx, ny);
}
}
return;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
cin >> a[i][j];
}
}
// 遍历整个地图,寻找连通块
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= m; j++)
{
if (vis[i][j] == 0 && a[i][j] == '#') // 如果该点没有访问过并且是草丛,则dfs搜索连通块
{
vis[i][j] = 1; // 记录已访问
dfs(i, j);
ans++; // 连通块个数++
}
}
}
cout << ans << '\n';
return 0;
}