蓝桥杯_基础训练_2n皇后问题
题目描述
问题描述
给定一个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
问题解决
主要思路
- 首先应该搞清楚什么条件下可以
判定
两个皇后是在同一行、同一列、同一条对角线
,根据上图我们明白两个公式right=row - line
和left= row + line
由于right
可能为负数,我们可一个给他们统一加一个+n
- 明白了这一点我们可以建立三个数组:
line、right、left
用来存储皇后同一行、同一列、同一条对角线
的情况。 - 接下来我们就可以通过
DFS
的方式来使棋子每个尝试一遍,看能否放置整盘。
代码
import java.util.Scanner;
public class Main {
static int n,sum=0;
static int[][] white= new int[10][10];
static int[] white_line=new int[10];static int[] white_right=new int[20];static int[] white_left=new int[20]; // 创建判定条件数组,用来记录皇后的情况
static int[] black_line=new int[10];static int[] black_right=new int[20];static int[] black_left=new int[20];//同理,只是来存储黑色的
static int[][] a =new int[10][10];
public static void main(String[] args) {
Scanner scanner= new Scanner(System.in);
n=scanner.nextInt();
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
a[i][j]=scanner.nextInt();
}
}
//使用dfs 传入参数1,即第一行
dfsWhite(1);
System.out.println(sum);
}
static void dfsWhite(int x){
//白色皇后放置完成结束条件,开始放置黑色皇后
if (x == n+1) {
dfsBlack(1);
return;
}
//循环列来尝试放置皇后
for (int i = 1; i <= n; i++) {
//判定放置皇后的位置 斜线、水平、竖直、是否有其他皇后
if (white_line[i]!=1&&white_left[x+i]!=1&&white_right[x-i+n]!=1&&a[x][i]!=0) {
// 存储现在皇后的情况
white[x][i]=1;
white_line[i]=1;
white_left[x+i]=1;
white_right[x-i+n]=1;
dfsWhite(x+1);
//如果不不能放置的话,返回操作,将描述情况数组全置为 0
white[x][i]=0;
white_line[i]=0;
white_left[x+i]=0;
white_right[x-i+n]=0;
}
}
}
//黑色与白色同理,只是重复了一遍
static void dfsBlack(int x){
if (x == n+1) {
sum+=1;
return;
}
for (int i = 1; i <= n; i++) {
if (black_line[i]!=1&&black_left[x+i]!=1&&black_right[x-i+n]!=1&&a[x][i]!=0&&white[x][i]!=1) {
black_line[i]=1;
black_left[x+i]=1;
black_right[x-i+n]=1;
dfsBlack(x+1);
black_line[i]=0;
black_left[x+i]=0;
black_right[x-i+n]=0;
}
}
}
}
black_line[i]=0;
black_left[x+i]=0;
black_right[x-i+n]=0;
}
}
}
}