LabyrinthAlgorithm

105 阅读1分钟

迷宫的最短路径

给定一个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];
    }
}

开发者涨薪指南

48位大咖的思考法则、工作方式、逻辑体系