数水坑
哈喽,大家好,我是赏月君,今天做一下广度优先搜索的题目——数水坑,废话少说,上题目。
题目描述
由于近期的降雨,农民约翰的田地里的许多地方都积水了,用一个N×M(1<=N<=100;1<=M<=100)的网格图表示。每个网格中有水(“W”)或是旱地(“.”)。一个网格与周围的八个网格相连,而一组相连的网格视为一个水坑。农夫约翰想知道他的地里形成了多少个水坑。给出一张农夫约翰的田地图,确定当中有多少个水坑。
输入
第一行:两个空格隔开的整数:N和M
第二行到第N+1行:每行M个字符,每个字符是‘W’或‘.’,它们表示网格图中的一排。字符之间没有空格。
输出
一行:水坑的数量
样例输入
10 12
W........WW.
.WWW.....WWW
....WW...WW.
.........WW.
.........W..
..W......W..
.W.W.....WW.
W.W.W.....W.
.W.W......W.
..W.......W.
样例输出
3
题目思路
定义一个方向数组dir[8][2],代表八个方向,定义一个地图数组和标记数组。结构体来记录具体位置。
首先,输入地图,循环遍历找到‘W’, 并且这个‘W’之前没有被标记过,那么就以它为起点,搜索出一片水坑,并将其全部标记。搜索时同样利用了队列。先将起始点放入队列,并标记已经走过,只要队列不空,就一直搜下去(注:是向八个方向搜索)。每搜索到一个水坑就让计数器加一,直到搜完整个地图。
代码实现
#include<bits/stdc++.h>
using namespace std;
int dir[8][2]={0,1,1,0,0,-1,-1,0,1,1,1,-1,-1,1,-1,-1};//八个方向
int m,n,sum=0;
char a[105][105];//地图
bool b[105][105]={0};//标记数组
//利用结构体解决
struct Point{
int x,y;
//构造函数
Point(int _x,int _y):x(_x),y(_y){
}
};
//判断x,y是不是在范围之内
bool in(int x,int y){
return 0<=x&&x<n&&0<=y&&y<m;
}
//广度优先搜索
int bfs(int sx,int sy){
queue<Point> q;//定义队列 q
bool key=0;//标记变量
q.push(Point(sx,sy));//将起始点放入队列
b[sx][sy]=1;//记录第一个已经走过
while(!q.empty()){
int x=q.front().x;//取得x坐标
int y=q.front().y;//取得y坐标
q.pop();//移出队列
//八个方向搜索
for(int i=0;i<8;i++){
//朝着一个方向搜索
int tx=x+dir[i][0];
int ty=y+dir[i][1];
if(in(tx,ty)&&a[tx][ty]=='W'&&!b[tx][ty]){
q.push(Point(tx,ty));//继续走
b[tx][ty]=1;//标记
key=1;//标记
}
}
}
if(key)return 1;
else return 0;
}
int main(){
cin>>n>>m;
//输入地图
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
cin>>a[i][j];
}
}
//循环遍历找水坑
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(a[i][j]=='W'&&!b[i][j]){
bfs(i,j);
sum++;//找到一个sum++一次
}
}
}
cout<<sum<<endl;
}
OK,解决了。