试题 基础练习 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
对于这道题,我们可以先试试4×4
4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
开始第一行第一列放皇后a
a 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
然后在第二行开始从第一列到第四列放皇后
a 1 1 1
1 1 a 1
1 1 1 1
1 1 1 1
然后再第三行开始从第一列到第四列放皇后
a 1 1 1
1 1 a 1
0 0 0 0
1 1 1 1 发现第三行放不下 回到上一步 并且把上一步的a再往后移动一次 再次循环判断继续。 大概逻辑是这样。用一个方法来检查能不能放。用一个方法递归实现上面的。加一个判断是否放完皇后。
具体在代码里注释。
import java.util.Scanner;
public class Main {
static int n,count=0; //n表示棋盘的大小,count则为上文提到的计数变量记录放置方法的个数
static int map[][]; //二维数组表示棋盘
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc =new Scanner(System.in);
n=sc.nextInt(); //相关变量的录入
map=new int[n][n];
for(int i=0;i<n;i++) //棋盘具体值的录入
for(int j=0;j<n;j++)
map[i][j]=sc.nextInt();
Put(0,2); //从第一行开始进行白皇后的放置,2代表黑皇后,3代表白皇后
System.out.println(count); //当所有的方法都寻找完成后,输出找到的方法个数
}
private static void Put(int h, int s) { //放置皇后的方法 h:行 s:皇后
// TODO Auto-generated method stub
if(h==n) { //进行当前类型皇后的放置数量是否达到要求,即是否到了棋盘的最后一行
if(s==2) {
Put(0,3); //如果黑皇后放置成功,则进行黑皇后的放置
}else {
count++; //放置方法招到了一种,计数变量进行值加一
}
return ; //当前整体放置过程结束,进行程序的回溯
}else {
for(int i=0;i<n;i++) //对每一行的值逐个进行操作
{
if(map[h][i]!=1)continue; //当前位置是否为1的判断
if(Check(h,i,s)){ //是否满足题目要求判断,满足赋值
map[h][i]=s;
}
else {
continue; //不满足,同一行的下一个位置
}
Put(h+1,s); //下一行皇后的放置
map[h][i]=1; //回溯法的关键
}
return ; //进行相应的回溯
}
}
private static boolean Check(int h, int i, int s) {
// TODO Auto-generated method stub
for(int q=h-1;q>=0;q--) { //判断正上方是否有皇后
if(map[q][i]==s) return false; // 1 1 1 1
} // 1 1 1 1
for(int q=h-1,w=i-1;q>=0&&w>=0;q--,w--) { //判断左上方是否有皇后 // 1 1 1 1
if(map[q][w]==s) return false; // 1 1 1 1
}
for(int q=h-1,w=i+1;q>=0&&w<n;q--,w++) { //判断右上方是否有皇后
if(map[q][w]==s) return false;
}
return true; //都满足没有皇后的情况下放置皇后 因为是一行一行从上往下的所以不用考虑下面的行的问题。
}
}
参考链接:https://blog.csdn.net/pangjunwei/article/details/78572874