问题描述
给定一个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;
}
}