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
二、算法分析
- 从给定题目的初步分析可以看出,本题要实现的是最短路径问题
- 实现矩阵的最短路径有多种方法,常见的可以使用深搜DFS和广搜BFS
- 今天我们给小朋友们用BFS进行实现,顺便学一下BFS是如何进行搜索的
- 首先小朋友们要了解什么是BFS,BFS是一种图遍历算法,用于在图数据结构中按层次展开图的节点,并逐个按层次访问节点。起始点作为第一层,与其直接相连的节点作为第二层,依次类推。
- 在我们这里就是按四个方向遍历整个矩阵;广度优先搜索使用队列数据结构来实现
- 实现过程:算法从起始节点开始,将起始节点入队,并标记为已访问。然后从队列中取出一个节点,访问该节点,并将其未访问的邻居节点加入队列。然后再从队列中取出一个节点,访问该节点,并将其未访问的邻居节点加入队列。以此类推,直到队列中没有节点为止,然后输出步数即可;因为在整个探索过程中,所有路径都是同时逐层从近到远探索,所以首先到达终点的路径一定最短。
- 所以我们在使用BFS进行算法实现之前呢,小朋友们需要先了解什么是队列,以及队列的性质
- 队列的原理及使用,小朋友们可以点击数据结构:队列详解 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
五、考点分析
难度级别:难,这题相对而言在于题目分析和算法的实现,具体主要考查如下:
- 分析题目,找到解题思路
- 充分掌握结构体和数组的使用
- 掌握队列的实现原理及相应的应用
- 学会广度优先算法原理并掌握相关用法
- 学会输入流对象cin的使用,从键盘读入相应的数据
- 学会for循环的使用,在确定循环次数的时候推荐使用学会
- 掌握输出流对象cout的使用,与流插入运算符 << 结合使用将对象输出到终端显示
- 学会分析题目,算法分析,将复杂问题模块化,简单化,从中找到相应的解题思路
- 充分掌握变量定义和使用、分支语句、循环语句和广度优先算法的应用
PS:方式方法有多种,小朋友们只要能够达到题目要求即可!