利用广度优先搜索解决迷宫问题
题目描述
给定一个迷宫(用二维数组存放),需要从一个起点走到终点(只允许上下左右走),0代表可走,1代表障碍物不可走,请找出从起点走到终点的最短路径。
样例解释
第一行输入n和m分别为二维数组(迷宫)的行和列,接着n行m列的迷宫,最后一给出两个坐标(x1,y1) (x2,y2)为起点和终点。(坐标中(x,y)为第x行第y列,而不是数学坐标系中的坐标)。
输入样例:
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
输出样例:
min=7
因为懒,哈哈,不想自己定义队列,所以用的 C++中队列的库函数,这里我整理了 C++中栈和队列库函数的一些用法
stack <int> S; //定义一个整型栈 S
S.push(a); //入栈
S.top(); //取栈顶
S.pop(); //出栈
S.empty(); //判空
queue <int> Q; //定义一个整型队列 Q
Q.push(a); //入队
Q.front(); //取队首
Q.pop(); //出队
Q.empty(); //判空
C++代码:
#include <bits/stdc++.h>
using namespace std;
struct Node{
int x;//坐标
int y;
int count;//步数
};
int main()
{
int next[4][2]={ {0,1},{1,0},{0,-1},{-1,0} };//方向数组
int a[50][50],book[50][50],i,j,n,m,endx,endy,flag;
struct Node start,temp;//起始位置,和暂存节点的变量
queue <struct Node> Q;//定义出一个队列 Q
scanf ("%d%d",&n,&m);//输入迷宫为n行m列
for (i=1;i<=n;i++)
{ //输入迷宫 0可走 1不可走
for (j=1;j<=m;j++)
scanf ("%d",&a[i][j]);
}
scanf ("%d%d%d%d",&start.x,&start.y,&endx,&endy);//输入起始位置和结束位置
start.count=0;//步数刚开始是 0
Q.push(start);//将起始节点入队
flag=0;
while (1)
{
for (i=0;i<4;i++)//按顺序扩展每个方向
{
temp=Q.front();//取队首节点
temp.x=temp.x+next[i][0];//扩展结点等于首节点加上方向数组
temp.y=temp.y+next[i][1];
temp.count++;//步数增加 1
if (temp.x<1||temp.x>n||temp.y<1||temp.y>m)//判断是否越界
continue;
if (a[temp.x][temp.y]!=1&&book[temp.x][temp.y]!=1)//判断是否能走和是否走过
{
Q.push(temp);//扩展
book[temp.x][temp.y]=1;//标记已经走过
}
if (temp.x==endx&&temp.y==endy)//已经走到终点
{
flag=1;
break;//第一次走到终点时即使最短路径,则无需将剩余路径走完
}
}
Q.pop();//每把一个节点的下一步全部扩展完时就将此节点出队
if (flag==1)
break;//结束死循环
}
printf ("min=%d",temp.count);
return 0;
}