迷宫的最短路径
给定一个N* M的迷宫。迷宫由墙壁和通道组成,每一步可以向相邻的上下左右四个点移动。请求出从起点到终点所需的最小步数。
限制条件:
N,M <= 100
输入及结果
java算法
import java.awt.Point;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
/**
* @author yangshuai
* @version 创建时间:2015-10-19 下午5:55:44
* 类说明 :走出迷宫的最短步数
*
1 2 1 1 1 1 1 1 1 1
0 0 0 0 0 0 1 0 0 1
0 1 0 1 1 0 1 1 0 1
0 1 0 0 0 0 0 0 0 0
1 1 0 1 1 0 1 1 1 1
0 0 0 0 1 0 0 0 0 1
0 1 1 1 1 1 1 1 0 1
0 0 0 0 1 0 0 0 0 0
0 1 1 1 1 0 1 1 1 0
0 0 0 0 1 0 0 0 3 1
*/
public class LabyrinthAlgorithm {
/**
* 0表示可移动的点,1表示不可移动到的点即墙壁,2表示迷宫的起点,3表示迷宫的终点。
*/
private static int CAN_MOVE = 0;
private static int CAN_NOT_MOVE = 1;
private static int STRART_LOCATION = 2;
private static int END_LOCATION = 3;
private static int a[][] = new int[100][100];
/**
* 宽
*/
private static int N;
/**
* 高
*/
private static int M;
public static void main(String[] args) {
System.out.println("欢迎来走迷宫,请输入以下几个参数:");
Scanner scanner = new Scanner(System.in);
System.out.println("迷宫的高:");
N = scanner.nextInt();
System.out.println("迷宫的宽:");
M = scanner.nextInt();
System.out.println("接下来,请输入迷宫数据:0表示可移动的点,1表示不可移动到的点即墙壁,2表示迷宫的起点,3表示迷宫的终点");
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
a[i][j] = scanner.nextInt();
if (a[i][j] == STRART_LOCATION) { //存储其实位置
sx = i;
sy = j;
}else if (a[i][j] == END_LOCATION) { //存储终点位置
gx = i;
gy = j;
}
}
}
System.out.println("计算开始:" + System.currentTimeMillis());
int result = solve();
System.out.println("完成计算:" + System.currentTimeMillis());
if (result == INF) {
System.out.println("你无法走出迷宫");
}else {
System.out.println("走 "+ result +" 步即可走出迷宫");
}
}
/**
* 起始坐标
*/
private static int sx, sy;
/**
* 终点坐标
*/
private static int gx, gy;
/**
* 用来存储四个方向移动的向量, 右, 下, 左, 上
*/
private static int dx[] =new int[]{1, 0, -1, 0}, dy[] =new int[]{0, 1, 0, -1};
private static final int INF = 10000000;
/**
* 用来存储从起点到某一点的距离,初始化为INF
*/
private static int d[][] = new int[100][100];
/**
* 求出,从(sx, sy) 到 (gx, gy)的最短距离, 如果无法到达则是INF
*/
private static int solve(){
// 初始化距离存储
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
d[i][j] = INF;
}
}
Queue<Point> queue = new LinkedList<Point>();
// 把起点加进队列
queue.offer(new Point(sx, sy));
// 起点到起点的距离为0
d[sx][sy] = 0;
// 循环,直到队列为空
while (!queue.isEmpty()) {
// 从队列最前端取出元素, 并从队列中移除该元素
Point point = queue.poll();
// 如果是终点,则退出循环, 结束搜索
if (point.x == gx && point.y == gy) break;
// 遍历四个方向, 右, 下, 左, 上
for (int i = 0; i < 4; i++) {
// 移动后的点用(nx, ny)存储
int nx = point.x + dx[i];
int ny = point.y + dy[i];
// 移动后的点在迷宫范围内, 且可以移动
if (nx >= 0 && ny >=0 && nx < N && ny < M && a[nx][ny] != CAN_NOT_MOVE && d[nx][ny] == INF ) {
// 把这个点加到队列中
queue.offer(new Point(nx, ny));
// 该点的移动距离是上个点的距离加1
d[nx][ny] = d[point.x][point.y] + 1;
}
}
}
return d[gx][gy];
}
}