题目链接点这里
BFS是一个很重要的算法常用于解决边的权重相同时的最短路径问题
本文主要讲解三维BFS走迷宫在用法和实践与二维BFS的区别
我们知道,简单的来说BFS = 队列,对于C++来说,走迷宫有现成的STL可以使用只需要调用头文件:
#include <queue>//头文件
二维走迷宫点的存储和取点方法:
typedef pair<int,int> PII;//或者pair<char,char>,视具体情况而定
queue<PII> q;//队列q用于存储点
q.push({x,y});//点入队
auto t = q.front();//取队首元素,t的类型为PII
int tx = t.first,ty = t.second;//取队首元素的两个方向上的位置
需要注意的是pair的实现依靠的是结构体,因此在解决三维BFS迷宫问题时只需定义一个结构体来表示z,x,y方向即可:
struct pos{
int first;
int second;
int third;
};//存储点
再来简单说一下三维数组:
以a[3][2][2]为例,如果把三维数组比作一个立方体的话,那么这个立方体的底边是一个2*2的正方形,高为3的立方体,注意三维数组的高维度是写在最前面的,也就是立方体的z
int arr[3][2][2] = {0,1,2,3,4,5,6,7,8,9,10,11};//相当于3个2*2的二维数组
//下面四行代码相当于立方体的第一层
printf("%d ",arr[0][0][0]);
printf("%d\n",arr[0][0][1]);
printf("%d ",arr[0][1][0]);
printf("%d\n",arr[0][1][1]);
//下面四行代码相当于立方体的第二层
printf("%d ",arr[1][0][0]);
printf("%d\n",arr[1][0][1]);
printf("%d ",arr[1][1][0]);
printf("%d\n",arr[1][1][1]);
//下面四行代码相当于立方体的第三层
printf("%d ",arr[2][0][0]);
printf("%d\n",arr[2][0][1]);
printf("%d ",arr[2][1][0]);
printf("%d\n",arr[2][1][1]);
以题目为例,下面来看一下具体代码是如何实现的
题目链接点这里
AC代码:
//1.三维数组的高:z,底面宽:x,底面长:y,在输入的同时记录
// 起点(z1,x1,y1),终点(z2,x2,y2)
//2.定义一个数组用于记时,定义一个结构体用于存储点(z,x,y)
//3.转向数组每次可以向六个方向的任一方向移动一格,每
// 次移动一格时间++
//4.移动后需判断移动后的点是否在矩阵内
//5.如果从起点到达终点的时间为-1则被困,否则输出时间
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int N = 35;
int h,w,l;//高、宽、长
int z1,x1,y1;//起点
int z2,x2,y2;//终点
char g[N][N][N];//高、行、列
int d[N][N][N];//从起点到某点的最短时间
int dx[6] = {1,-1,0,0,0,0},dy[6] = {0,0,1,-1,0,0},dz[6] = {0,0,0,0,1,-1};//转向数组
struct pos{
int first;
int second;
int third;
};//存储点
void BFS(int z,int x,int y)
{
queue<pos> q;//存储点的队列
memset(d,-1,sizeof d);//初始化
d[z1][x1][y1] = 0;
q.push({z1,x1,y1});//起点入队
while(!q.empty())
{
pos t = q.front();
q.pop();//移除队首元素
for(int i = 0; i < 6; i++)
{
int tz = t.first + dz[i],tx = t.second + dx[i],ty = t.third + dy[i];//移动后的点
if(tz >= 1 && tz <= h && tx >= 1 && tx <= w && ty >= 1 && ty <= l && g[tz][tx][ty] != '#' && d[tz][tx][ty] == -1)
{//在矩阵内、可以走、第一次走
q.push({tz,tx,ty});
d[tz][tx][ty] = d[t.first][t.second][t.third] + 1;
}
}
}
}
int main()
{
while(true)
{
cin >> h >> w >> l;
if(h == 0 && w == 0 && l == 0) return 0;
for(int i = 1; i <= h; i++)//高
for(int j = 1; j <= w; j++)//行
for(int k = 1; k <= l; k++)//列
{
cin >> g[i][j][k];
if(g[i][j][k] == 'S') z1 = i,x1 = j,y1 = k;//起点
if(g[i][j][k] == 'E') z2 = i,x2 = j,y2 = k;//终点
}
BFS(z1,x1,y1);//从起点开始搜索
if(d[z2][x2][y2] == -1)//如果值未被更新说明没有到达该点的路径
cout << "Trapped!" << endl;
else
cout << "Escaped in " << d[z2][x2][y2] << " minute(s)." << endl;
}
return 0;
}
简单总结一下三维BFS走迷宫与二维的主要区别就是定义结构体来表示点、转向数组由4个方向改为6个方向
有问题您就来问我,别偷偷藏在心里