大致思路:开辟两个二维数组分别保存迷宫的地图和地图上每个点到原点的距离,地图上的1作为墙/走过的标志,0为可走的位置,利用向量数组dx、dy进行点的移动,每走一点则将距离保存在对应位置,继续走,直到有一个方向走到终点结束(此时正好也是最短的距离)。
利用queue实现
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N = 110;
typedef pair<int,int> PII;
int g[N][N];//保存地图
int f[N][N];//保存距离
int n,m;
void bfs(int a,int b)
{
queue<PII> q;
q.push({a,b});//把初始点入栈
while(!q.empty())
{
PII start = q.front();
q.pop();
g[start.first][start.second] = 1;//标记已经走过
int dx[4] ={1,0,-1,0},dy[4] = {0,-1,0,1};
//上下左右四个方向向量,每个数组对应位置组合成为一个向量
//按照上面数组顺序四个方向向量分别是下,左,上,右
for(int i = 0;i < 4;i++)
{
int x = start.first + dx[i], y = start.second + dy[i];//从当前点开始向四个方向移动
if(!g[x][y])//不是墙
{
g[x][y] = 1;//变成墙,表示走过了,避免下一步再返回
f[x][y] = f[start.first][start.second] + 1;//对应位置保存距原点的距离
q.push({x,y});//移动到下一个点
}
}
}
cout << f[n][m];//输出终点的距离累计
}
int main()
{
memset(g,1,sizeof(g));//初始化全设置成墙,去掉了判断越界的步骤,等地图录入结束后相当于在原地图基础上四周砌了一圈墙
cin >> n >> m;
for(int i = 1;i <= n;i++)
for(int j = 1; j <= m;j++)
cin >> g[i][j];
bfs(1,1);//从左上角开始走
return 0;
}
数组模拟queue实现
#include<iostream>
#include<cstring>
using namespace std;
const int N = 110;
typedef pair<int,int> PII;
int g[N][N];//保存地图
int f[N][N];//保存距离
int n,m;
PII q[N*N];
int bfs()
{
int hh = 0,tt = 0;//hh为头,tt为尾
q[0] = {0,0};
memset(f, -1 ,sizeof f);//-1表示没走过
f[0][0] = 0;//起点走过了
int dx[4] = {0,-1,0,1},dy[4] = {1,0,-1,0};//四个向量
while(hh<=tt)//队列不为空
{
PII t = q[hh++];//取头的数据
for(int i = 0;i < 4;i++)
{
int x = t.first + dx[i],y = t.second + dy[i];
if(g[x][y] == 0 && f[x][y] == -1)//不是墙能走且没走过
{
f[x][y] = f[t.first][t.second] + 1;//保存距离起点的距离
q[ ++ tt ] = {x, y};//新坐标入队
}
}
}
return f[n-1][m-1];//返回终点值
}
int main()
{
memset(g, 1, sizeof g);//这样初始化不用考虑越界
cin >> n >> m;
for(int i = 0;i < n;i++)
for(int j = 0; j < m;j++)
cin >> g[i][j];
cout << bfs();
return 0;
}