三维BFS走迷宫(POJ - 2251)

题目链接点这里

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个方向

有问题您就来问我,别偷偷藏在心里

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值