经典搜索算法——广度优先搜索【数水坑(深搜/广搜连通块)】

4 篇文章 0 订阅
3 篇文章 0 订阅

数水坑
哈喽,大家好,我是赏月君,今天做一下广度优先搜索的题目——数水坑,废话少说,上题目。
题目描述
由于近期的降雨,农民约翰的田地里的许多地方都积水了,用一个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,解决了。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值