真正带你入门与深析BFS的本质与BFS代码实战训练——Floor Fill 模型及经典例题(1)

BFS概述:

BFS,宽度优先搜索(广度优先搜索),是一种能够相对于暴力搜索,能够有效的降低复杂度的搜索方式,其中的用途和作用大致有两个:

①在边权为1的时候,求路线的最小值;

②是一种基于迭代的算法,不会爆栈(相对于DFS而言);(因为他是广度优先的,不是向深度优先的。)

今天我们来讲解一个经典的BFS模型:Flood Fill(我把它命名为FF模型)

FF模型:

Flood Fill,洪水灌溉模型,如果你提前接触过搜索,你肯定知道这个模型的工作原理,我们可以用手动的方式模拟出来:

相信图解已经描述的很清楚了,在讲完具体模板的工作原理以后,我将用三道经典的衍生题,为大家彻底讲清楚BFS 的FF模型;(本期讲解第一道衍生题)

《池塘计数》

记住,正确的,以学生角度来思考的方式,写代码的时候,BFS应该先写main()函数,再写BFS实现函数!

解题思路请看分析:

main函数的书写:

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N = 1010;
char w[N][N];
bool st[N][N];

//BFS函数先第二步再写 
//先写Main函数!!  
int main()
{
	for(int i = 0;i<n;++i) 
		for(int j=0;j<m;++j)
		{
			cin>>w[i][j];
		}
	
	int cnt = 0;
	for(int i = 0;i<n;++i) 
		for(int j=0;j<m;++j)
		{
			if(w[i][j]=='W' && !st[i][j]){
				bfs(i,j);
				cnt++;
			}
		}
		cout << cnt << '\n';
		return 0;
}

?

  BFS函数的书写:

#include<bits/stdc++.h>
using namespace std;
int n,m;
const int N = 1010;

char w[N][N];
bool st[N][N];

//BFS函数先第二步再写 
const int M = N*N;//队列是二维的,队列中存储的东西的数量不超过N*N;
#define x first //取队列的第一个元素的时候,用x代替,好写 
#define y second//取队列的第而个元素的时候,用y代替,好写

typedef pair<int,int> PII;//定义二维,方便书写 

PII q[M]; //定义队列,bFS都是用队列实现的 

void bfs(int sx,int sy)//这里就是“搜(i,j) ” 的意思
{
	int hh = 0, tt= 0;//定义队头指针与队尾指针
	q[0] = {sx,sy};//将起点放入队中(二维);
	st[sx][sy]= true;//起点被访问过了,标记为true; 
	while(hh<=tt)//保证队头指针在队尾指针的前面(队列不空的情况下) 
	{
			PII t= q[hh++] ;//取出队头元素,用t接受,并向后移动队头指针! 
	 		
	 	for(int i = t.x-1;i<=t.x+1;++i)//遍历点(i,j)附近的九宫格 
		{
			for(int j = t.y-1;j<=t.y+1;++j)//遍历点(i,j)附近的九宫格 
			{
			 	//开始筛选情况,不符合不合法的就continue它
				if(i == t.x && j== t.y) continue;	//排除(i,j)本身 
				//(剩下八个点) 
				if(i<0 || i>=n || j<0 || j>=m) continue;
				if(w[i][j] == '.' || st[i][j]) continue;
				
				//符合情况的点 入队
				q[++tt]  = {i,j};
				st[i][j] = true;//标记为true 
			}
		} 
	}
	
} 


//先写Main函数!! 
int main()
{
	cin>>n>>m;
	 
	for(int i = 0;i<n;++i) 
		for(int j=0;j<m;++j)
		{
			cin>>w[i][j];
		}
	
	int cnt = 0;
	for(int i = 0;i<n;++i) 
		for(int j=0;j<m;++j)
		{
			if(w[i][j]=='W' && !st[i][j]){
				bfs(i,j);
				cnt++;
			}
		}
		cout << cnt << '\n';
		return 0;
}

此题迎刃而解!

总结:

BFS在FF问题的时候,既有模板的加持,又有思维分析的深度,嘴里默念着思路写代码,是最好的方式。这就是BFS—FF问题的第一题,下期再见!

下期内容:BFS—FF(2)问题

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值