BFS
宽搜
题目:
给定一个n*m的二维整数数组,用来表示一个迷宫,数组中只包含0或1,其中0表示可以走的路,1表示不可通过的墙壁。
最初,有一个人位于左上角(1, 1)处,已知该人每次可以向上、下、左、右任意一个方向移动一个位置。
请问,该人从左上角移动至右下角(n, m)处,至少需要移动多少次。
数据保证(1, 1)处和(n, m)处的数字为0,且一定至少存在一条通路。
题解
package Chapter3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 迷宫
* @author vccyb
*
*/
public class P844 {
static final int N = 110;
//g地图矩阵 d距离矩阵
static int[][] g = new int[N][N], d = new int[N][N];
//q 队列
static PII[] q = new PII[N*N];
static int n;
static int m;
static int bfs(){
int hh=0,tt=-1;
q[0] = new PII(0,0);//从初始点开始
//入队了, tt++
tt++;
//初始化距离为-1
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
d[i][j] = -1;
}
}
//
d[0][0] = 0; //将初始点的距离初始化为0
int[] dx = {-1,0,1,0}; // 左 上 右 下
int[] dy = {0,1,0,-1}; // {-1,0} {0,1} {1,0} {0,-1}
while(hh<=tt){
//出队 队列不空,每次出队
PII t = q[hh++]; //队列后进先出。
for(int i=0;i<4;i++){
int x = t.getFirst()+dx[i];
int y = t.getSecond()+dy[i];
//什么意思?遍历这个点的前后左右
if(x >= 0 && x < n && y >= 0 && y < m && g[x][y] == 0 && d[x][y] == -1){
//注意最后一个条件d[x][y] = -1,说明是没有走过的
//1. 距离跟新+1
d[x][y] = d[t.getFirst()][t.getSecond()]+1;
//2. 新的点进队呀
q[++tt] = new PII(x,y);
}
}
}
//所有的点进队和出队了
return d[n-1][m-1]; //返回终点的距离
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//输入地图矩阵
String[] line = br.readLine().split(" ");
n = Integer.parseInt(line[0]); //地图的行数 n
m = Integer.parseInt(line[1]); //地图的列数 m
for(int i=0;i<n;i++){
String[] str = br.readLine().split(" ");
for(int j=0;j<m;j++){
g[i][j]=Integer.parseInt(str[j]);
}
}
//Test======测试地图是否输入
// for(int i=0;i<n;i++){
// for(int j=0;j<m;j++){
// System.out.print(g[i][j]+" ");
// }
// System.out.println();
// }
//.调用bfs咯
System.out.println(bfs());
br.close();
}
}
//手写pair
//用这个存储两个点的坐标
class PII{
private int first;
private int second;
public PII(){
}
public PII(int first, int second) {
this.first = first;
this.second = second;
}
public int getFirst() {
return this.first;
}
public int getSecond() {
return this.second;
}
}