刷題藍橋杯(java)---2N皇后
阿新 • • 發佈:2019-02-14
/*問題描述 給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少种放法?n小於等於8。 輸入格式 輸入的第一行為一個整數n,表示棋盤的大小。 接下來n行,每行n個0或1的整數,如果一個整數為1,表示對應的位置可以放皇后,如果一個整數為0,表示對應的位置不可以放皇后。 輸出格式 輸出一個整數,表示總共有多少种放法。 樣例輸入 4 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 樣例輸出 2 樣例輸入 4 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 樣例輸出 0 */ import java.util.Scanner; public class Main { static int n; static int[] bq;// 記錄黑皇后的位置 static int[] wq;// 白皇后 static int number = 0; static int[][] map; public static void main(String[] args) { Scanner in = new Scanner(System.in); n = in.nextInt(); bq = new int[n]; wq = new int[n]; map = new int[n][n]; for (int i = 0; i < n; i++) {// 初始化棋盤 for (int j = 0; j < n; j++) map[i][j] = in.nextInt(); } bqueen(0);//0對應0行,t System.out.println(number); } static void wqueen(int t) { // 白皇后,先去看黑皇后的,思路是先黑後白 boolean panduan = false;// 用來判斷是否可以放 for (int i = 0; i < n; i++) {// 找到當前行合適的長度,i表示列 if (map[t][i] == 1 && bq[t] != i) {// 棋盤上可以放 for (int k = 0; k < t; k++) {// 遍歷之前的皇后並判斷當前位置是否可以放, // 注意k<t,比較的是當前行之前的皇后 if (wq[k] == i | Math.abs(k - t) == Math.abs(wq[k] - i)) {// 同列或同對角線,一定不同行 panduan = true;// 當前位置不能放 break; } } if (!panduan) {// 能放 wq[t] = i; if (t == n - 1) {// 白皇后到達終點 number++; } else wqueen(t + 1);// 進入下一步 } else panduan = false;// 復原防止影響下一次的比較 } } return; } static void bqueen(int t) {// 每行的操作 // 黑皇后 boolean panduan = false;// 用於標記當前列是否可放 for (int i = 0; i < n; i++) {// 找到當前行合適的長度,i表示列 if (map[t][i] == 1) {// 棋盤上可以放 for (int k = 0; k < t; k++) {// i表示列,遍歷之前的皇后並判斷當前位置是否可以放, // 注意k<t,比較的是當前行之前的皇后 if (bq[k] == i || Math.abs(k - t) == Math.abs(bq[k] - i)) {// 同列或同對角線,一定不同行 panduan = true;// 當前位置不能放 break; } } if (!panduan) {// 能放 bq[t] = i; if (t == n - 1) {// 找到終點加入白皇后 wqueen(0);// 進入白皇后的放置 } else bqueen(t + 1);// 進入下一行 } else panduan = false;// 復原防止影響下一次的比較 } } return;// 當前行沒有合適的地方可以放置皇后即為函式的正常結束(可不寫return) } }