算法学习019 BFS实现迷踪步 c++算法学习 中小学算法思维学习 比赛算法题解 信奥算法解析

C++BFS实现迷踪步

一、题目要求

1、编程实现

        有一个 n 行 m 列的方格迷宫,用 0 表示可以通过,用 1 表示不可以通过,每一步可以向上、下、左、右任意方向移动一格,请计算从左上角(1,1)位置移动到右下角(n,m)位置,最少移动多少步?

2、输入输出

输入描述:第一行输入矩阵大小n和m(3<=n<=m<=40)

                  接下来n行n列的数字(0和1组成)

输出描述:只有一行,一个整数,即从左上角到右下角最少移动多少步

输入样例:

6 8

0 1 0 0 0 1 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0

输出样例:

12

二、算法分析

  1. 从给定题目的初步分析可以看出,本题要实现的是最短路径问题
  2. 实现矩阵的最短路径有多种方法,常见的可以使用深搜DFS和广搜BFS
  3. 今天我们给小朋友们用BFS进行实现,顺便学一下BFS是如何进行搜索的
  4. 首先小朋友们要了解什么是BFS,BFS是一种图遍历算法,用于在图数据结构中按层次展开图的节点,并逐个按层次访问节点。起始点作为第一层,与其直接相连的节点作为第二层,依次类推。
  5. 在我们这里就是按四个方向遍历整个矩阵;广度优先搜索使用队列数据结构来实现
  6. 实现过程:算法从起始节点开始,将起始节点入队,并标记为已访问。然后从队列中取出一个节点,访问该节点,并将其未访问的邻居节点加入队列。然后再从队列中取出一个节点,访问该节点,并将其未访问的邻居节点加入队列。以此类推,直到队列中没有节点为止,然后输出步数即可;因为在整个探索过程中,所有路径都是同时逐层从近到远探索,所以首先到达终点的路径一定最短。
  7. 所以我们在使用BFS进行算法实现之前呢,小朋友们需要先了解什么是队列,以及队列的性质
  8. 队列的原理及使用,小朋友们可以点击数据结构:队列详解 c++信息学奥赛基础知识讲解这这篇博客进行系统的学习,然后再回来尝试做一下这道题

三、程序编写

#include<bits/stdc++.h>
using namespace std;
int grid[101][101],visited[101][101];//gird存放矩阵数值,visited标记是否访问过
int n,m;//n和m为矩阵行列,mindis为最短距离
int f4[4][2]={{0,1},{0,-1},{-1,0},{1,0}};//四个方向搜索
struct node //每个单元格作为一个节点
{
	int x;
	int y;
	int dis;
};
int BFS(int,int,int);//坐标及最短路径
int main()
{
	//输入矩阵
	cin >> n >> m;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			cin >> grid[i][j];
	//计算最短路径
	cout <<	BFS(1,1,0);
}
int BFS(int x,int y,int z)
{
	visited[x][y] = 1;//起始点标记访问
	queue <node> q;	//声明一个队列
	node start,next;//声明队列的起点和下一个点
	//设置起始节点属性
	start.x = x;
	start.y = y;
	start.dis = z;
	q.push(start);//入队
	while(!q.empty())//队不为空
	{
		start = q.front();//获取队首元素
		q.pop();//出队
		if(start.x == n && start.y == m)//如果当前节点到到最后一个点,返回长度
			return start.dis;
		for(int i=0;i<=3;i++)//四个方向搜索
		{
			//获取下一个节点的属性
			next.x = start.x + f4[i][0];
			next.y = start.y + f4[i][1];
			next.dis = start.dis + 1;
			//下一个节点有路径到达且未访问过
			if(grid[next.x][next.y] == 0 && !visited[next.x][next.y])
			{
				visited[next.x][next.y] = 1;//访问
				q.push(next);//入队
			}
		}
	}
	return -1;
}

 本文作者:小兔子编程 作者首页:https://blog.csdn.net/frank2102

四、运行结果

6 8

0 1 0 0 0 1 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 0 0 1 0 0 0 0
0 1 0 0 0 1 0 0

12

五、考点分析

难度级别:难,这题相对而言在于题目分析和算法的实现,具体主要考查如下:

  1. 分析题目,找到解题思路
  2. 充分掌握结构体和数组的使用
  3. 掌握队列的实现原理及相应的应用
  4. 学会广度优先算法原理并掌握相关用法
  5. 学会输入流对象cin的使用,从键盘读入相应的数据
  6. 学会for循环的使用,在确定循环次数的时候推荐使用学会
  7. 掌握输出流对象cout的使用,与流插入运算符 << 结合使用将对象输出到终端显示
  8. 学会分析题目,算法分析,将复杂问题模块化,简单化,从中找到相应的解题思路
  9. 充分掌握变量定义和使用、分支语句、循环语句和广度优先算法的应用

PS:方式方法有多种,小朋友们只要能够达到题目要求即可!

六、推荐资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小兔子编程

您的鼓励是我创作优质案例的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值