算法设计与分析: 5-12 罗密欧与朱丽叶的迷宫问题

5-12 罗密欧与朱丽叶的迷宫问题

问题描述

罗密欧与朱丽叶的迷宫。罗密欧与朱丽叶身处一个 m×n 的迷宫中,如图所示。每一个方格表示迷宫中的一个房间。这 m×n 个房间中有一些房间是封闭的,不允许任何人进入。 在迷宫中任何位置均可沿 8 个方向进入未封闭的房间。罗密欧位于迷宫的(p,q)方格中,他 必须找出一条通向朱丽叶所在的(r,s)方格的路。在抵达朱丽叶之前,他必须走遍所有未封 闭的房间各一次,而且要使到达朱丽叶的转弯次数为最少。每改变一次前进方向算作转弯一 次。请设计一个算法帮助罗密欧找出这样一条道路。

《算法设计与分析: 5-12 罗密欧与朱丽叶的迷宫问题》

对于给定的罗密欧与朱丽叶的迷宫,编程计算罗密欧通向朱丽叶的所有最少转弯道路。

数据输入:
第一行有 3 个正整数 n,m,k,分别表示迷宫的行数,列数和封闭的房间数。接下来的 k 行中,每行 2 个正整数,表示被封闭的房间所在的行号和 列号。最后的 2 行,每行也有 2 个正整数,分别表示罗密欧所处的方格(p,q)和朱丽叶所处 的方格(r,s)。

Java

package Chapter5HuiSuFa;

import java.util.Scanner;

public class RomeoYuJulietDeMiGong {

    private static int[] dx = {0,-1,-1,0,1,1,1,0,-1};
    private static int[] dy = {0,0,1,1,1,0,-1,-1,-1};
    private static int n,m,k;
    private static int dirs,best,count;
    private static int x,y,x1,y1;
    private static int[][] board,bestb;

    private static int MAX = 100000;

    public static void main(String[] args){
        Scanner input = new Scanner(System.in);

        while (true){
            best = MAX;
            dirs = 0;
            n = input.nextInt();
            m = input.nextInt();
            k = input.nextInt();

            board = new int[n+1][m+1];
            bestb = new int[n+1][m+1];

            for(int i=1; i<=n; i++)
                for(int j=1; j<=m; j++)
                    board[i][j] = 0;

            for(int i=1; i<=k; i++){
                int row = input.nextInt();
                int col = input.nextInt();
                board[row][col] = -1;
            }

            x = input.nextInt();
            y = input.nextInt();
            x1 = input.nextInt();
            y1 = input.nextInt();

            board[x][y] = 1;

            //最开始只能向下走(1,0),本程序中即为(dx[5],dy[5]): x(行)增加,y(列)不变
            //所以最开始的di设为5,不然方向会多一次比较,会多1
            search(1,x,y,5);

            System.out.println(best);
            System.out.println(count);
            for(int i=1; i<=n; i++){
                for(int j=1; j<=m; j++)
                    System.out.print(bestb[i][j]+" ");
                System.out.println();
            }

        }
    }

    private static void search(int dep, int x, int y, int di){
        if(dep==m*n-k && x==x1 && y==y1 && dirs<=best){
            if(dirs < best){
                best = dirs;
                count = 1;
                save();
            }else
                count++;
            return;
        }
        if(dep==m*n-k || x==x1 && y==y1 || dirs>best) return;
        else
            for(int i=1; i<=8; i++){
                if(stepok(x+dx[i], y+dy[i])){
                    board[x+dx[i]][y+dy[i]] = dep+1;
                    if(di != i) dirs++;
                    search(dep+1,x+dx[i],y+dy[i],i);
                    if(di != i) dirs--;
                    board[x+dx[i]][y+dy[i]] = 0;
                }
            }
    }

    private static boolean stepok(int x, int y){
        return (x>0 && x<=n && y>0 && y<=m && board[x][y]==0);
    }

    private static void save(){
        for(int i=1; i<=n; i++)
            for(int j=1; j<=m; j++)
                bestb[i][j] = board[i][j];
    }
}

Input & Output

3 4 2
1 2
3 4
1 1
2 2
6
7
1 -1 7 6 
2 10 5 8 
3 4 9 -1 

Reference

王晓东《计算机算法设计与分析》(第3版)P183

    原文作者:迷宫问题
    原文地址: https://blog.csdn.net/IOIO_/article/details/81108267
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞