【回溯】八皇后變換-2n皇后
阿新 • • 發佈:2020-12-25
問題描述
給定一個n*n的棋盤,棋盤中有一些位置不能放皇后。現在要向棋盤中放入n個黑皇后和n個白皇后,使任意的兩個黑皇后都不在同一行、同一列或同一條對角線上,任意的兩個白皇后都不在同一行、同一列或同一條對角線上。問總共有多少种放法?n小於等於8。
輸入
輸入的第一行為一個整數n,表示棋盤的大小。
接下來n行,每行n個0或1的整數,如果一個整數為1,表示對應的位置可以放皇后,如果一個整數為0,表示對應的位置不可以放皇后。
輸出
輸出一個整數,表示總共有多少种放法。
解法:回溯回溯
思路
- 先填好白皇后,再填黑皇后
- 放置黑皇后時注意不能與白皇后重合
程式碼
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;
}
}