java backtracking递归(骑士)

时间:2019-05-05 09:49:11

标签: java recursion backtracking

这就像N皇后问题。 给定的董事会规模(行,列) 和要成为骑士的人数(骑士)

在给定的棋盘上我可以容纳多少个骑士?

我将使用嵌套的int数组

1将代表骑士占领那个地方。

99将表示自从已有骑士袭击以来没有骑士可以进入的地方。

0将表示骑士可以进入的空白区域。

运行调试后,我发现骑士(3,3,5);

[-1,-1,-1] [-99,-1,-99]在这里,我被困住了,必须回溯。 [-99,-99,-99]

但是在回溯中,看看board [0] [0]骑士的位置将如何攻击-> board [2] [1]

然后,登机[0] [2]骑士会攻击->登机[2] [1]

因此,当我在板上[0] [2]后退并撤消骑士时,

它还撤消了-99,这是不应该的,因为有多个骑士同时攻击该空间...

对于解决此问题的任何提示或建议,我将不胜感激。

public class knightsPlacement {

    public static void knights(int row, int col, int knights) {
        if(row < 0 || col < 0 || knights < 0) {
            System.out.println("Enter new parameters");
            return;
        }

        int [][] board = new int[row][col];

        for(int i = 0; i < board.length; i++) {
            for(int y = 0; y < board[0].length; y++) {
                board[i][y] = 0;
            }
        }


                solveKnights(board, 0, 0, knights);


    }

    public static boolean solveKnights(int[][] board, int row, int col, int knights) {


        if(row < 0 || row >= board.length || col < 0 || col >= board[0].length) {
            return false;
        }
        if(board[row][col] == -1 || board[row][col] == -99) {
            return false;
        }


        board[row][col] = -1;
        knights = knights -1;


        if(knights == 0) {
            return true;
        }
        if((row-2) >= 0 && (col-1) >=0 ) {
            board[row-2][col-1] = -99;
        }
        if((row-1) >= 0 && (col-2) >= 0) {
            board[row-1][col-2] = -99;
        }
        if((row-2) >= 0 && (col+1) < board[0].length) {
            board[row-2][col+1] = -99;
        }
        if((row-1) >= 0 && (col +2) < board[0].length) {
            board[row-1][col+2] = -99;
        }
        if((row+2) < board.length && (col-1) >=0 ) {
            board[row+2][col-1] = -99;
        }
        if((row+1) < board.length && (col-2) >= 0) {
            board[row+1][col-2] = -99;
        }
        if((row+2) < board.length && (col+1) < board[0].length) {
            board[row+2][col+1] = -99;
        }
        if((row+1) < board.length && (col+2) < board[0].length) {
            board[row+1][col+2] = -99;
        }
        for(int i = 0; i < board.length; i++) {
            System.out.println(Arrays.toString(board[i]));
        }
        System.out.println();


    for(int rowCount = 0; rowCount < board.length; rowCount++) {
        for(int colCount = 0; colCount < board[0].length; colCount++) {
                            if(solveKnights(board, rowCount,colCount, knights))return true; 
                        }
                    }



            board[row][col] = 0;
            knights = knights +1;

            if((row-2) >= 0 && (col-1) >=0 ) {
                board[row-2][col-1] = 0;
            }
            if((row-1) >= 0 && (col-2) >= 0) {
                board[row-1][col-2] = 0;
            }
            if((row-2) >= 0 && (col+1) < board[0].length) {
                board[row-2][col+1] = 0;
            }
            if((row-1) >= 0 && (col +2) < board[0].length) {
                board[row-1][col+2] = 0;
            }
            if((row+2) < board.length && (col-1) >=0 ) {
                board[row+2][col-1] = 0;
            }
            if((row+1) < board.length && (col-2) >= 0) {
                board[row+1][col-2] = 0;
            }
            if((row+2) < board.length && (col+1) < board[0].length) {
                board[row+2][col+1] = 0;
            }
            if((row+1) < board.length && (col+2) < board[0].length) {
                board[row+1][col+2] = 0;
            }

            return false;

    }

}

1 个答案:

答案 0 :(得分:0)

我设法创建了解决方案。我将在下面放一个与您的问题相关的摘录,并让您找出其余的内容,因为本练习旨在培训您。

private int solveKnights(int[][] board, int row, int knights) {
    // PLACEHOLDER
    int totalPlacements = 0;
    for (int currentCol = 0; currentCol < board[0].length; currentCol++) {
        if (validPlacement(board, row, currentCol)) {
            board[row][currentCol] = 1;
            totalPlacements += solveKnights(board, row + 1, knights - 1);
            board[row][currentCol] = 0;  // undo knight placement on backtracking
        }
        // PLACEHOLDER
    }
    // PLACEHOLDER
    return totalPlacements;
}

private boolean validPlacement(int[][] board, int row, int col) {
    for (int currentRow = 0; currentRow < board.length; currentRow++) {
        if (board[currentRow][col] != 0) {
            return false;
        }
    }
    for (int currentCol = 0; currentCol < board[0].length; currentCol++) {
        if (board[row][currentCol] != 0) {
            return false;
        }
    }
    return true;
}

如您所见,我仅使用值0和1(技术上为0,任何非0值)。这样可以简化回退一点后的电路板。