1. 程式人生 > 其它 >【回溯】八皇后變換-2n皇后

【回溯】八皇后變換-2n皇后

技術標籤:五大常用演算法dfs演算法

原題連結

問題描述

給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少种放法?n小於等於8。

輸入

輸入的第一行為一個整數n,表示棋盤的大小。
接下來n行,每行n個0或1的整數,如果一個整數為1,表示對應的位置可以放皇后,如果一個整數為0,表示對應的位置不可以放皇后。

輸出

輸出一個整數,表示總共有多少种放法。


解法:回溯回溯

思路

  1. 先填好白皇后,再填黑皇后
  2. 放置黑皇后時注意不能與白皇后重合

程式碼

import java.util.Scanner;

public class Main {

    static int result = 0;
    static int[][] arr;

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        arr = new int[n][n];
        for (int i = 0; i < n; i++)
{ for (int j = 0; j < n; j++) { arr[i][j] = scanner.nextInt(); } } int[] ideaWhite = new int[n]; twoNQueen(ideaWhite, 0, n); System.out.println(result); } /** * 先放白皇后,再放黑皇后 * @param ideaWhite * @param i * @param n * @return 有多少种放法 */
private static void twoNQueen(int[] ideaWhite, int i, int n) { if(i == n){ int[] ideaBlack = new int[n]; // 白皇后已經放置好了,現在開始放置黑皇后 blackQueen(ideaWhite,ideaBlack, 0, n); }else { for (int j = 0; j < n; j++) { ideaWhite[i] = j; if(judgeWhite(ideaWhite, i)){ twoNQueen(ideaWhite, i + 1, n); } } } } /* 放置黑皇后 */ private static void blackQueen(int[] ideaWhite, int[] ideaBlack, int i, int n) { if(i == n){ result ++; }else { for (int j = 0; j < n; j++) { ideaBlack[i] = j; if(judgeBlack(ideaWhite, ideaBlack, i)){ blackQueen(ideaWhite, ideaBlack, i + 1, n); } } } } /* 判斷已經放置好的黑皇后是否符合規則 */ private static boolean judgeBlack(int[] ideaWhite, int[] ideaBlack, int i) { if(arr[i][ideaBlack[i]] != 1){ return false; } // 白皇后與黑皇后重合(注意是小於或等於i,因為要判斷當前行) for (int ii = 0; ii <= i; ii++) { if(ideaWhite[ii] == ideaBlack[ii]){ return false; } } for (int ii = 0; ii < i; ii++) { // 同列 || 主斜線 || 副斜線 if(ideaBlack[i] == ideaBlack[ii] || i - ideaBlack[i] == ii - ideaBlack[ii] || i + ideaBlack[i] == ii + ideaBlack[ii]){ return false; } } return true; } /* 判斷已經放置好的白皇后是否符合規則 */ private static boolean judgeWhite(int[] ideaWhite, int i) { if(arr[i][ideaWhite[i]] != 1){ return false; } for (int ii = 0; ii < i; ii++) { if(ideaWhite[i] == ideaWhite[ii] || i - ideaWhite[i] == ii - ideaWhite[ii] || i + ideaWhite[i] == ii + ideaWhite[ii]){ return false; } } return true; } }

提交結果