迷宫问题(广度优先搜索BFS与最短路径)

描述:

定义一个二维数组:

int maze[5][5] = {

	0, 1, 0, 0, 0,

	0, 1, 0, 1, 0,

	0, 0, 0, 0, 0,

	0, 1, 1, 1, 0,

	0, 0, 0, 1, 0,

};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

左上角到右下角的最短路径,格式如样例所示。

input:

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

output:

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

该题的主要讲解和思路都写在注释中,方法简单,更方便食用哦

代码实现:

/*
		广度优先搜索  BFS 
		
		执行顺序是,先用que保存所有的情况,一个一个进行向外衍生, 
		顺序,先执行第一个,判断第一个有多少种走法,全部储存到que中,然后分a,b;a用于遍历,b用于储存 
		用a向后推,遍历该是否满足,不满足的话进行该位置的下一个方向的判断,如果找到位置的话,就用b进行储存
		que中的p的作用是保存下一步的方向,如果p[i] = 1,那么就对照dx进行坐标的加减。 
		注意:走过的地方都要进行标记,防止重复走。 
*/ 

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int arr[10][10];     // 储存内容 
bool used[10][10];  // 标记是否走过。 
int fx = 0,fy = 0,endx = 4,endy = 4;
int dx[4] = {1,-1,0,0};// 坐标的移动,配合47,40...行的使用 
int dy[4] = {0,0,1,-1};
struct point  // 建立结构体用来记录走的方法 
{
	int x,y;        // 记录坐标 
	int p[100];     // 记录下一步的方向 
	int steps;     // 记录步数 
}que[30],u;    // que用来储存所以的情况,广泛遍历, 

void bfs()
{
	int a=0,b=0;
	que[b].x = 0,que[b].y = 0,que[b].steps = 0,que[b].p[que[b].steps] = 0;   // 储存初始位置的坐标,步数,方向 
	b++;                                                                     // 向后推一位 
	used[fx][fy] = true; //标记已经走过了 
	while(1)
	{
		u = que[a++];                       // 遍历,判断是否满足和记录在这个坐标上的下一个位置 
		if(u.x == endx&&u.y == endy)        // 如果满足条件,输出 
		{
			int xx = 0,yy = 0;
			cout << "(" << xx << ", " << yy << ")" << endl;
			for(int i = 1; i <= u.steps; i++)
			{			
				xx = xx+dx[u.p[i]],yy = yy + dy[u.p[i]];
				printf("(%d, %d)\n",xx,yy);
			}
			return ;
		}
		for(int i = 0; i <= 3; i++)
		{
			int nx = u.x+dx[i],ny = u.y+dy[i];
			if(nx>=0&&nx<5&&ny>=0&&ny<5&&!used[nx][ny]&&arr[nx][ny] == 0)  // 防止越界和去除不让走的和去除重复的 
			{
				que[b].x = nx,que[b].y = ny;     // 储存下一个位置(52-58); 
				que[b].steps = u.steps+1;
				for(int i = 0; i <= u.steps; i++)
				{
					que[b].p[i] = u.p[i];
				}
				que[b].p[que[b].steps] = i;
				b++;
				used[nx][ny] = true;     // 标记已经走过。 
			}
		}
	}
}

int main (void)
{
	for(int i = 0;i < 5; i++)  // 输入和初始化,不做解释。 
	{
		for(int j = 0; j < 5;j++)
		{
			scanf("%d",&arr[i][j]);
		}
	}
	memset(used,false,sizeof(used));
	bfs();
	
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值