给定一个 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
输出样例:
8
BFS用于求解最短路问题,且各边权重全为1(相等),一层一层往外搜。
运用BFS+队列,从起点走到终点,先到终点的即为最短距离。
BFS:搜索(满足条件)
队列:将满足条件的点入队,通过出队、入队的操作,一层一层往外扩展。
如:第一层搜到的为距离1,第二层为距离2,以此类推。
走迷宫:
同时满足以下条件:
(1)x,y大于等于0并且x
(2)走到的点为0,不为1。
g[x][y]=0;
(3)走到的位置还没被走过
d[x][y]=-1;
即if(x>=0&&x
更新满足条件点的距离,即将上一个点走过的距离加上 1
。先到终点的为最小值
即d[x][y]=d[t.first][t.second]+1;
再将满足条件的点入队, 用于继续判断。
即q[++tt]=new PII(x,y);
注:这里需要运用到PII类
作用1:获取x(行数)
、y(列数)
,用于上下左右移动+判断
作用2:将该点入队
即q[++tt]= new PII(x,y);
最后直接返回距离即可
即return d[n-1][m-1];
(注意数组下标从0开始)
注:BFS类似于一颗二叉树
注:到达交叉口的位置,将可走的点入队,再依次出队。
出队的每个点拿出来判断,如果下一个点可走,则将下一个点进入到队列尾中。
这样入队出队的操作保证了一层一层往外扩,并且搜索到的每一层的距离相等。
如搜索到第一层,为距离为1的点,第二层,为距离为2的点,依此类推。
import java.io.*;
public class Main{
static int N=110,hh,tt,n,m;
//N数据为100,多开10个单位,防止越界。
static int [][]g=new int[N][N];
static int [][]d=new int[N][N];
static PII []q=new PII[N*N];
//最多移动整个数组,即N行N列
public static int bfs() {
hh=0;//初始化队头
tt=-1;//初始化队尾
d[0][0]=0;//第0行第0列为入口
q[++tt]=new PII(0,0);//往队尾添加第一个点
int dx[]= {-1,0,1,0};
int dy[]= {0,1,0,-1};
/*
向上移动:
dx[0]=-1 dy[0]=0 (-1,0) 列不变,行数往上移
向右移动:
dx[1]=0 dy[1]=1 (0,1) 行不变,列数往右移
向下移动:
dx[2]=1 dy[2]=0 (1,0) 列不变,行数往下移
向左移动:
dx[3]=0 dy[3]=-1 (0,-1) 行不变,列数往左移
*/
while(hh<=tt) {
PII t=q[hh++];//取出队头
for(int i=0;i<4;i++) {
//向上、下、左、右移动
int x = t.first+dx[i];
int y = t.second+dy[i];
/*同时满足以下条件:
(1)x,y大于等于0并且x
if(x>=0&&x<n&&y>=0&&y<m&&g[x][y]==0&&d[x][y]==-1) {
d[x][y]=d[t.first][t.second]+1;//满足条件,则在原来走过的距离上加一,记录走过的距离。
q[++tt]=new PII(x,y);//再将该点(x,y)插入到队尾,用于下面的判断。
}
}
}
return d[n-1][m-1];//返回从起点到终点的距离,数组下标从0开始,即n-1,m-1
}
public static void main(String []args) throws IOException {
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
//BufferedWriter out = new BufferedWriter(new OutputStreamWriter(System.out));
String []s = in.readLine().split(" ");
n = Integer.parseInt(s[0]);
m=Integer.parseInt(s[1]);
for(int i=0;i<n;i++) {
String []st = in.readLine().split(" ");
for(int j=0;j<m;j++) {
g[i][j]=Integer.parseInt(st[j]);//读入数据
d[i][j]=-1;//初始化每行每一列的位置,代表还没走过。
}
}
System.out.println(bfs());//输出数字
//out.write(bfs());输出数字对应的字符
//out.close();
}
}
class PII{//PII
int first,second;
public PII(int first,int second){//构造方法
this.first=first;
this.second=second;
}
}