BFS 迷宫问题合集

针对迷宫问题,用到的技巧是不断出入队列,把队头元素弹出队列后,将转移得到的状态再放入队中,这样做到的是BFS的广度优先搜索,等于每次找到的都是离原点最近的状态,所以肯定最终得到的是最短路径。

在开始阶段有一部分初始化,

#include <queue>

#define INF 10005//到各点距离的最大值

#define MAXN  205//迷宫大小

struct node

{

    int x,int y;

    node(int a,int b)

    {

        x = a;y = b;

    }

    node(){} //这里可以说是这个结构体中最关键的一步,使用了面向对象程序设计的技巧 空构造方法

};
node s,t;//记录起始坐标以及终点坐标



 之后是全局变量区域

char maze[MAXN][MAXN];//存储迷宫字符串
int d[MAXN][MAXN];//到各点的距离
queue <node> que;//结构体类型的队列
int n,m;
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};


之后部分以最近所做的寻找键盘为例1,以SJY学长的四维迷宫作为例2来理解迷宫问题


例1 BJUTACM OPENJUDGE

183G:电脑键盘是否存在


总时间限制: 
1000ms 
内存限制: 
100000kB
描述

奇奇小朋友是一位哲学家,她是程序员希希的鼓励师。

希希每天回家以后都要工作到很晚,没有时间陪奇奇。

奇奇很想让希希多陪陪她,所以这一天,奇奇把家里的键盘藏了起来,这样希希回家以后就不能写代码了。

希希回家以后发现键盘不见了,他问奇奇键盘去哪儿了,奇奇说:

「也许键盘不见了,你就认识到键盘不存在了;

   也许是你认识到你应该多陪陪我了,所以键盘它就自己消失了」

聪明的你,请帮助因为失去了键盘而没有办法编程的希希找回他的键盘。

键盘被藏在房间里了,房间里有且仅有一柄键盘,但还有一些其他的物品。

房间里的空地可供通行,而放有物品的地方则不能通行。

你只能从入口进入房间,入口有且仅有一个。

在房间内的空地上你只能向前、后、左、右四个方向通行。

输入
第一行是一个整数 T,表示以下会有 T 个测试用例。
每个测试用例第一行有两个整数,R 和 C,
分别代表房间的长和宽。(1 <= R, C <= 200)
接下来是 R 行,每行 C 个字符,代表整个房间。
键盘用字符 'K' 表示,房间内的其他物品用字符 '#' 表示,空地用字符 'O' 表示。
房间的入口用 'I' 表示。
输出
对于每个测试用例:

如果你进入房间后成功找到了键盘,请输出一行形如 "Are you OK?"(不包含双引号)的字符串询问希希现在还好吗,根据你找到键盘所用的最少步数 n 将字符串中的 'O' 重复 n+1 遍;

如果你进入房间后无法找到键盘,请输出 "I have already eaten the keyboard." (不包含双引号)告诉希希键盘被你偷偷吃掉了。
样例输入
3
5 5
IO###
#O###
#OO##
##OO#
###OK
5 5
K#OOO
O#O#O
O#I#O
O###O
OOOOO
3 3
I#O
##O
OOK
样例输出
Are you OOOOOOOOK?
Are you OOOOOOOOOOOOOOOK?
I have already eaten the keyboard.





























































 代码

#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <vector>
#include <cstring>
#include <cmath>
#include <cstdlib>

#define INF 100005
#define MAXN 500
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
struct node {
	int x,y;
	node(int a,int b)
	{
		x = a;
		y = b;
	}
	node(){}
};
node s,t;
char maze[MAXN][MAXN];
int d[MAXN][MAXN];
queue <node> que;
int n,m;
int dx[4] = {1,0,-1,0};
int dy[4] = {0,1,0,-1};

int bfs()
{
	que.push(s);
	d[s.x][s.y] = 1;
	while(que.size()!=0)
	{
		node temp = que.front();
		que.pop();
		if(temp.x==t.x&&temp.y==t.y) 	return d[t.x][t.y];
		for(int i=0;i<4;i++)
		{
			int nx = temp.x + dx[i];
			int ny = temp.y + dy[i];
			if(nx>=0&&nx<n&&ny>=0&&ny<m&&maze[nx][ny]!='#'&&d[nx][ny]==INF)
			{
				d[nx][ny] = d[temp.x][temp.y] + 1;
				que.push(node(nx,ny));
			}
		}
	}
	return d[t.x][t.y];
}
int main(int argc, char** argv) {
	
	int p;
	scanf("%d",&p);
	for(int k=0;k<p;k++)
{
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++)
	{
		scanf("%s",maze[i]);
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			d[i][j] = INF;//初始化所有点距离为无穷大 
			if(maze[i][j]=='I') s = node(i,j);
			else if(maze[i][j]=='K') t = node(i,j);
		}
	}
	if(bfs()==INF) 
	{
	printf("I have already eaten the keyboard.\n");
	}
	else
	{
		printf("Are you ");
		for(int i=0;i<bfs()-1;i++)
		{
			printf("O");
	    }
		printf("K?\n"); 
		 
	}
}
	//system("pause");
	return 0;
}

例2 四维迷宫问题

分析:针对于四维迷宫,主要是多个方向的遍历更加困难 而且不能使用pair 必须使用结构体

lq17E:今

总时间限制: 
1000ms 
内存限制: 
256000kB
描述

20 年前的今天,曾经发生过一件轰动全球的大事。生活在四维空间中的三体人为了入侵地球,将地球空间的维度升到了四维,并设置了重重障碍,阻碍地球人联络增援。在全球人民的共同努力之下,地球人侥幸逃出了三体人布下的四维天罗地网,拯救了地球。但是出于安抚民心的需要,世界各国联合起来,共同抹去了这场星球之战的一切痕迹。现在,一名在那场战役用幸存的士兵找到了你,希望你重现当年的场景,挽回救球英雄们的尊严!

输入
第一行为四个整数,n, m, p, q (1 ≤ n, m, p, q ≤ 20)。
接下来的数据分为 n 组输入,每组有 m 个 p × q 字符矩阵,表示四维空间的最后三个维度。n 组输入共同表示整个四维迷宫。

迷宫中的字符有四种可能,为「.」、「#」、「S」和「T」,分别表示通道,障碍,起点和终点。其中起点和终点有且只有一对。每一步可以向相邻的 8 个方向的通道(或起点和终点)移动。

输入保证存在从起点到终点的路径。
输出
输出从起点到终点的最短路径的长度
样例输入
2 2 2 2
S.
##

#.
##


##
T#

#.
..
样例输出
6
 
     
#include <iostream>
#include <queue>
#define INF 10005
using namespace std;

char maze[20][20][20][20];
int color[20][20][20][20] = {0};//0代表没有访问过 1代表访问过 
int dd[20][20][20][20];
int uu[8] = {-1, 1, 0, 0, 0, 0, 0, 0}, vv[8] = {0, 0, -1, 1, 0, 0, 0, 0}, ww[8] = {0, 0, 0, 0, -1, 1, 0, 0}, zz[8] = {0, 0, 0, 0, 0, 0, -1, 1};
int n,m,p,q;
int sx,sy,sz,st;
struct  chucun//封装了四个坐标 
{
	int x;
	int y;
	int z;
	int t;
	chucun(int a, int b, int c, int d){
		x = a; y = b; z = c; t = d;
	}
	chucun(){}
};	
chucun s,t;
int tx,ty,tz,tt;
int flags = 1;
int flagt = 1;
bool judge(int w, int x, int y, int z){
	if (dd[w][x][y][z] != INF || w < 0 || w >= n || x < 0 || x >= m || y < 0 || y >= p || z < 0 || z >=q || maze[w][x][y][z] == '#')	return 0;
	return 1;
}
int bfs()
{
	queue<chucun>que;
	que.push(s);
	dd[s.x][s.y][s.z][s.t] = 0;
//	printf("%d\t%d\t%d\t%d\n",s.x,s.y,s.z,s.t);
	while(que.size())
	{
		chucun temp = que.front(); 
//		printf("&&&&&&&&&\n");
		que.pop();
//		printf("#########\n"); 
		if(temp.x==t.x&&temp.y==t.y&&temp.z==t.z&&temp.t==t.t)	break;
		for(int i=0;i<8;i++)
		{
		 
			int nx = temp.x + uu[i];
			int ny = temp.y + vv[i];
			int nz = temp.z + ww[i];
			int nt = temp.t + zz[i];
			//	printf("nx = %d\tny = %d\tnz = %d\tnt = %d\n",nx,ny,nz,nt);
		//	if(nx>=0&&nx<n&&ny>=0&&ny<m&&nz>=0&&nz<p&&nt>=0&&nt<q&&maze[nx][ny][nz][nt]!='#'&&dd[nx][ny][nz][nt]==INF)
			if(judge(nx,ny,nz,nt))
				{
						//	printf("nx = %d\tny = %d\tnz = %d\tnt = %d\n",nx,ny,nz,nt);
					dd[nx][ny][nz][nt] = dd[temp.x][temp.y][temp.z][temp.t]+1;	//	printf("%d\t%d\t%d\t%d\n",qqq.x,qqq.y,qqq.z,qqq.t);
					que.push(chucun(nx,ny,nz,nt));
						//temp
				}
		}
	}
	return dd[t.x][t.y][t.z][t.t];
}
int main(void)
{
	char temp;
	char temp2;
	int count =  0;

	scanf("%d%d%d%d",&n,&m,&p,&q);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			for(int k=0;k<p;k++)
			{
				for(int l=0;l<q;l++)
				{
					do
					{
						scanf("%c",&temp); 
						if(temp=='#'||temp=='S'||temp=='T'||temp=='.')
						{
							temp2 = temp;
							break;
					 	} 
					}while(1);
					maze[i][j][k][l] = temp2;
					dd[i][j][k][l] = INF;
					if(temp2=='S')	
					{
						s = chucun(i,j,k,l);
					//	flags = 0;
					}
					if(temp2=='T')
					{
						t = chucun(i,j,k,l);
					//	flagt = 0;//printf("###%d\t%d\t%d\t%d\n",tx,ty,tz,tt);
					}
					
					if(count==n*m*q*p)	goto a;
				}
			}
		}
	}
	a: 
//	for(int i=0;i<n;i++)
//		for(int j=0;j<m;j++)
//			for(int k=0;k<p;k++)
//				for(int l=0;l<q;l++)
//					printf("%c",maze[i][j][k][l]);
//					
					
	printf("%d",bfs());
	return 0;
				
	
} 
这段代码由于是早期所写,可能BUG 以及无用的部分很多




猜你喜欢

转载自blog.csdn.net/curiousliu/article/details/79930833