附上题目:P1596水坑
题目
由于近期的降雨,雨水汇集在农民约翰的田地不同的地方。我们用一个NxM(1<=N<=100;1<=M<=100)网格图表示。每个网格中有水('W') 或是旱地('.')。一个网格与其周围的八个网格相连,而一组相连的网格视为一个水坑。约翰想弄清楚他的田地已经形成了多少水坑。给出约翰田地的示意图,确定当中有多少水坑。
[1]输入格式:
第1行:两个空格隔开的整数:N 和 M 第2行到第N+1行:每行M个字符,每个字符是'W'或'.',它们表示网格图中的一排。字符之间没有空格。
[2]输出格式:
一行:水坑的数量
[3]输入输出样例:
[4]题解:
- 找到连在一起的'W',找到一整块,就让计数器加1
- 所以要怎样找到连续的'W'呢?这里就要用到搜索,先找到一个'W之后和它有连接的都得标记
- 要注意自己找到过的'W'就得将它标记为不可以再算的
要不然会计数器输出的数字会比答案大
需要注意:
这个题好像用不上回溯,一定要注意判断时需要用到哪些条件,因为这个可能会导致重复遍历,即结果会比较大:
[5]代码(带注释):
//前面做的搜索的题,多多少跟回溯有点关系
//但这个题好像不用,它只用遍历做相应的标记就可以了
#include<stdio.h>
int n,m;
char str[100][100]={0};
int dir[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
int way[100][100]={0};
int cout=0;
void print()
{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%c",str[i][j]);
}
printf("\n");
}
return;
}
void dfs(int x,int y)
{
for(int i=0;i<8;i++)
{
int nx=x+dir[i][0];
int ny=y+dir[i][1];
//不能超过边界,也不能走走过的地方
if(nx>=0&&ny>=0&&nx<n&&ny<m&&way[nx][ny]==0&&str[nx][ny]=='W')
{
way[nx][ny]=1;
dfs(nx,ny);
}
}
}
int main()
{
scanf("%d %d",&n,&m);
//吸收上面得回车符
getchar();
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
scanf("%c",&str[i][j]);
}
//到下一行,会输入一个回车符
getchar();
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
//一定要跳过被标记的地方,因为那里是在上一个水坑里面的
//所以得跳过,开始就是这里出现了问题,导致遍历整个田地
//得到了‘W’的数量
if(str[i][j]=='W'&&way[i][j]==0)
{
//printf("%d %d\n",i,j);
way[i][j]=1;
dfs(i,j);
//要注意计数器所摆放得位置,计数器没摆对位置就会导致输出得数据不是我们想要的
cout++;
}
}
}
print();
printf("%d\n",cout);
return 0;
}