题目描述
给定一个 n×m 的二维整数数组,用来表示一个迷宫,数组中只包含 0 或 1,其中 0 表示可以走的路,1 表示不可通过的墙壁。
最初,有一个人位于左上角 (1,1) 处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角 (n,m) 处,至少需要移动多少次。
数据保证 (1,1) 处和 (n,m) 处的数字为 0,且一定至少存在一条通路。
输入格式
第一行包含两个整数 n 和 m。
接下来 n 行,每行包含 m 个整数(0 或 1),表示完整的二维数组迷宫。
输出格式
输出一个整数,表示从左上角移动至右下角的最少移动次数。
数据范围
1≤n,m≤100
样例
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
算法
(BFS)
C++ 代码
#include<iostream>
#include<queue>
using namespace std;
const int MAX_N=205,MAX_M=205;
const int INF=1e8;
typedef pair<int ,int >PII;
char maze[MAX_N][MAX_M+1];//表示迷宫字符串的数组
int N,M;
int sx,sy;//start坐标
int gx,gy;//goal坐标
int d[MAX_N][MAX_M];//到各个位置的最短距离
//四个方向的向量
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
//求从(sx,sy)到(gx,gy)的最短距离
//如果无法达到,则是INF
int bfs()
{
queue<PII>que;
sx=0,sy=0;
gx=N-1,gy=M-1;
//吧所有位置都初始化为INF
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
d[i][j]=INF;
que.push(PII(sx,sy));
d[sx][sy]=0;
while(que.size())
{
PII p=que.front();que.pop();
//如果取出的状态是终点,则结束搜索
if(p.first==gx&&p.second==gy)break;
//四个方向的循环
for(int i=0;i<4;i++)
{
//移动后的坐标是(nx,ny)
int nx=p.first+dx[i],ny=p.second+dy[i];
//判断是否可以移动以及是否已经访问过(d[nx][ny]!=INF即为已经访问过)
if(0<=nx&&nx<N&&0<=ny&&ny<M&&d[nx][ny]==INF&&maze[nx][ny]=='0')
{
//可以移动的话,加入队列,并且到该位置的距离确定为到p的距离+1
que.push(PII(nx,ny));
d[nx][ny]=d[p.first][p.second]+1;
}
}
}
return d[gx][gy];
}
void solve()
{
int res=bfs();
cout<<res<<endl;
}
int main()
{
cin>>N>>M;
for(int i=0;i<N;i++)
{
for(int j=0;j<M;j++)
{
cin>>maze[i][j];
}
}
solve();
return 0;
}