基础练习 2n皇后问题:
资源限制:
时间限制:1.0s
内存限制:512.0MB
问题描述:
给定一个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[][] cc;//保存题中输入的二维数组
static int count = 0 , n;//count为最终答案 ,n为阶数
static int[] num1 , num2;//分别代表放置白皇后,黑皇后的数组
//下标代表行号,num1[1]=5,表示当前白皇后放置在第2行第6列
//num2同理
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
n = in.nextInt();
cc = new int[n][n];
num1 = new int[n];
num2 = new int[n];
for(int i=0;i<cc.length;i++) {
for(int j=0;j<cc[0].length;j++) {
cc[i][j] = in.nextInt();
}
}
run1(0);
System.out.println(count);
}
//x表示当前要放置x个皇后(从0开始算0,1,2,3,...,n-1)
public static void run1(int x) {
//如果对应白皇后放置到第n个,也就是放置等于第x个(x=数组长度)时,意味着白皇后当前已经找到一种放置的解,这个时候开始放置黑皇后,run2(0)
//当黑皇后放置完后退到这里return会白皇后的上一层,找下一种解法,依次这样...
if(x>=cc.length) {
run2(0);
return;
}
for(int i=0;i<n;i++) {
if(cc[x][i]==0) {
continue;
}
num1[x] = i;
if(check(x , num1)) {
run1(x+1);
}
}
}
public static void run2(int x1) {
if(x1>=cc.length) {
count++;
return;
}
for(int i=0;i<n;i++) {
if(cc[x1][i]==0 || num1[x1]==i) {
continue;
}
num2[x1] = i;
if(check(x1, num2)) {
run2(x1+1);
}
}
}
//num[i]==num[n] 表示放置在了同一列
//Math.abs(i-n)==Math.abs(num[i]-num[n]) 表示放置同一斜线上(45°)
public static boolean check(int n ,int[] num) {
for(int i=0;i<n;i++) {
if(num[i]==num[n] || Math.abs(i-n)==Math.abs(num[i]-num[n]) ) {
return false;
}
}
return true;
}
}
今天的学习到这里结束了。
这是之前写的,今天算是总计一下。
鄙人水平有限,若有写的不妥当打地方 还请大佬指正。
又看不懂的地方,留言给我。
最后最后。如果你看了有所收获,可不可以点赞(你觉得还可),评论(还不错给点支持),转发(谢谢谢~~)