算法设计与分析: 6-19 骑士征途问题

6-19 骑士征途问题

问题描述

在一个 n*n 个方格的国际象棋棋盘上,马(骑士)从任意指定方格出发,按照横 1 步竖2 步,或横 2 步竖 1 步的跳马规则,走遍棋盘的每一个格子,且每个格子只走 1 次。这样的 跳马步骤称为 1 个成功的骑士征途。例如,当 n=5 时的 1 个成功的骑士征途如下图所示。

《算法设计与分析: 6-19 骑士征途问题》

对于给定的 n 和 n*n 方格的起始位置 x 和 y。用分支限界法找出从指定的方格(x,y)出发 的一条成功的骑士征途。

数据输入:
第一行有 1 个正整数 n (1≤n≤10);第二行有 2 个正整 数 x 和 y,表示骑士的起始位置为(x,y)。

Java

package Chapter6FenZhiXianJieFa;

import java.util.*;

public class QiShiZhengTu {

    private static class Point implements Comparable{
        int x;
        int y;
        int step;
        int[][] board;

        public int compareTo(Object o){
            Point point = (Point) o;
            int result = Integer.compare(point.step, step);

            return result;
        }
    }

    private static int[] dx = {-2, -1, 1, 2, -2, -1, 2, 1};
    private static int[] dy = {-1, -2, -2, -1, 1, 2, 1, 2};

    private static int n;
    private static int[][] board;
    private static int startX,startY;

    private static Point E,N;
    private static Queue<Point> Q;

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

        while (true){
            n = input.nextInt();
            startX = input.nextInt();
            startY = input.nextInt();

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

            board[startX][startY] = 1;

            fifobb(step);
        }
    }

    private static void fifobb(int step){
        Q = new PriorityQueue<>();
        E = new Point();
        E.step = step;
        E.x = startX;
        E.y = startY;
        E.board = new int[n+1][n+1];
        arrayCopy(board, E.board);

        //搜索排列空间树
        while (true){
            if(answer()) {record(); break;}
            else
                for(int i=0; i<8; i++){
                    newNode(i);
                    if(constrain() && bound()) enQueue();
                }
            if(!getNext()) break;
        }
        output();
    }

    private static void record(){
        arrayCopy(E.board, board);
    }

    public static void arrayCopy(int[][] src, int[][] des){
        for(int i=0; i<src.length; i++)
            des[i] = Arrays.copyOf(src[i], src[i].length);
    }


    private static boolean getNext(){
        if(Q.isEmpty()) return false;
        E = Q.poll();
        E.board[E.x][E.y] = E.step;

        return true;
    }

    private static void enQueue(){
        N.step++;
        Q.add(N);
    }

    private static boolean bound(){
        return true;
    }

    private static boolean constrain(){
        if (N.x < 1 || N.y < 1 || N.x > n || N.y > n || N.board[N.x][N.y] != 0)
            return false;
        else
            return true;
    }

    private static void newNode(int i){
        N = new Point();
        N.x = E.x+dx[i];
        N.y = E.y+dy[i];
        N.step = E.step;
        N.board = new int[n+1][n+1];
        arrayCopy(E.board, N.board);
    }

    private static boolean answer(){
        return E.step==n*n;
    }

    private static void output(){
        if(E.step < n*n){
            System.out.println("No solution!");
        }else {
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= n; j++)
                    System.out.print(String.format("%4d", board[i][j]));

                System.out.println();
            }
        }
    }
}

Input & Output

5
1 3
  19  10   1  16  25
   2  15  18  11   6
   9  20   5  24  17
  14   3  22   7  12
  21   8  13   4  23

Reference

王晓东《计算机算法设计与分析》

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