题干:
蒜头君和他的朋友周末相约去召唤师峡谷踏青。他们发现召唤师峡谷的地图是由一块一块格子组成的,有的格子上是草丛,有的是空地。草丛通过上下左右 4 个方向扩展其他草丛形成一片草地,任何一片草地中的格子都是草丛,并且所有格子之间都能通过上下左右连通。如果用'#'
代表草丛,'.'
代表空地,下面的峡谷中有 2 片草地。
1 ##..
2 ..##
处在同一个草地的 2 个人可以相互看到,空地看不到草地里面的人。他们发现有一个朋友不见了,现在需要分头去找,每个人负责一片草地,蒜头君想知道他们至少需要多少人。
输入格式
第一行输入 n, m (1≤n,m≤100) 表示峡谷大小
接下来输入 n 行字符串表示峡谷的地形
输入格式
输出至少需要多少人
样例输入
5 6 .#.... ..#... ..#..# ...##. .#....
样例输出
5
问题分析:
这个问题其实就是问:一共有多少片草地。(和蓝桥杯的一道题目类似)
解决方法:
使用的方法就是“深搜”。首先找到一个草丛,即‘#’,然后从该草丛处开始搜索来确定有多少草丛与该草丛直接或间接相连,搜索完毕之后得到一片草地,这片草地只需要一个人,不需要把标记还原;
然后再从未被标记过的草丛处开始搜索,即重复上述步骤,直到所有的草丛都被搜过。
注意:要区分开我所说的“草丛”和“草地”,多个相连的“草丛”连成一片草地。
代码如下:
#include<iostream>
using namespace std;
char map[101][101];
int book[101][101] = {0};
int next1[4][2]={{0,1},{-1,0},{0,-1},{1,0}};
int n,m;
void dfs(int r,int c)
{
for(int k = 0;k < 4;++k)
{
int rr = r+next1[k][0];
int cc = c+next1[k][1];
if(rr < 0 || cc < 0 || rr >= n || cc >= m) continue;
if(map[rr][cc] == '#' && !book[rr][cc])
{
book[rr][cc] = 1;
map[rr][cc] = '.';
dfs(rr,cc);
//book[rr][cc] = 0;
}
}
}
int main()
{
cin >> n >> m;
for(int i = 0;i < n;++i)
{
for(int j = 0;j < m;++j)
{
cin >> map[i][j];
}
}
int ans = 0;
for(int i = 0;i < n;++i)
{
for(int j = 0;j < m;++j)
{
if(map[i][j] == '#' && !book[i][j])
{
//从未被标记过的草丛开始搜索,草地数+1
ans++;
book[i][j] = 1;
dfs(i,j);
}
}
}
cout << ans << endl;
return 0;
}