问题描述
给定一个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
样例输出
给定一个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
分析:
首先,考虑,普通的八皇后问题是怎么实现的。
①遍历每一个位置,n*n每一个位置,每次遍历的时候判断,该位置是否能放下旗子。
②使用一个一维数组保存每一列的位置。原因。因为每一行是不可以放置重复旗子的。
使用一维数组。 每一个坐标代表行号。 。。 该坐标里面的值代表这一行,这一列 在哪个位置放下旗子
使用一维数组可以减少遍历次数
2n皇后实现:
每次遍历出一个 只放置 黑色棋子 的棋盘 放法。
复制出一个棋盘。 所有已放置黑色棋子的位置 设置为0 代表已经不可以放置棋子了。
遍历出该棋盘所有 可以放置的白棋子位置的方法
import java.util.*;
public class Main {
static int n ;
static int count = 0;//次数和
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
n = input.nextInt();
int[][] begin = new int[n][n];
int[] pos = new int[n];//方便遍历的一维数组
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
begin[i][j] = input.nextInt();
}
}
setBlack(begin,pos,0);//开始测试所有黑色棋子摆放方式
System.out.println(count);
}
public static boolean isSafe(int[] pos,int row){//验证该行放置的旗子是否和其他行冲突
for(int i=0;i<row;i++){
if(pos[i]==pos[row]||Math.abs(i-row)==Math.abs(pos[i]-pos[row])){
return false;
}
}
return true;
}
public static void setBlack(int[][] black,int[] pos,int row){
if(row==n){//当所有位置摆放完毕后
int[][] white = new int[n][n];
int[] pos1 = new int[n];
//按照现在已经摆满黑棋子的情况,创造出一个新的棋盘
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(black[i][j]==1&&pos[i]!=j){//该位置没有放置白棋子,并且原本可以放置棋子
white[i][j] = 1;
}
}
}
setWhite(white,pos1,0);
}else{
//该行的每一列。//试试他能不能放下棋子
for(int i=0;i<n;i++){
pos[row] = i;
if(black[row][i]==1&&isSafe(pos,row)){//判断该位置放棋子对还是错
setBlack(black,pos,row+1);
}
}
}
}
public static void setWhite(int[][] white,int[] pos,int row){
if(row==n){
count++;
}else{
for(int i=0;i<n;i++){
pos[row] = i;
if(white[row][i]==1&&isSafe(pos,row)){
setWhite(white,pos,row+1);
}
}
}
}
}