一、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
//2n皇后问题
import java.util.*;
public class TwoQueen {
// 记录总数
public static int count;
// 棋盘大小
public static int size;
// 定义的棋盘
public static int chess[][];
public static void main(String[] args) {
TwoQueen twoQueen = new TwoQueen();
Scanner sc = new Scanner(System.in);
size =sc.nextInt();
chess=new int[size][size];
// 设定什么位置可放置皇后 1表示可放 0表示不可放
for (int i=0;i<size;i++)
{
for(int j=0;j<size;j++)
{
chess[i][j] = sc.nextInt();
}
}
twoQueen.put(0,2);
System.out.println(count);
}
//定义将皇后棋放入棋盘的方法 2表示白皇后 3表示黑皇后
// 1.先判断棋盘位置是否为1 因为只有1才能放棋
// 2.判断棋子是否不满足处于同一行 同一列 同一对角线
// 3.先放白皇后棋,当白皇后棋放好后,再放置黑色棋
public void put(int row,int queen ) //row 表示行 chess表示皇后棋
{
if(row==size){
if(queen==2)
put(0,3);
// 这里不加else 回溯一次 加一次
else
count++;
return;
}
else
{
for(int i=0;i<size;i++){
if(chess[row][i]!=1) continue;
if(judge(row,i,queen)){
chess[row][i]=queen;
}else{
continue;
}
// 当一行放置了皇后后,就跳入下一行
put(row+1,queen);
// 每次递归返回结果时要将此步的皇后位置重新变为1
chess[row][i]=1;
}
// 递归回溯
return;
}
}
// 定义判断棋子是否不满足处于同一行 同一列 同一对角线的方法
// 传回的参数是当前行,当前列,和当前的皇后名
public boolean judge(int row,int column,int queen){
//因为数组的右边 以及下方没有元素所以不用考虑
// 先判断同一列的上方
for(int i=row-1;i>=0;i--){
if(queen==chess[i][column])
return false;
}
// 考虑左上方
for(int i=row-1,w=column-1;i>=0&& w>=0;i--,w--){
if(queen==chess[i][w])
return false;
}
// 考虑右上方
for(int i=row-1,w=column+1;i>=0&& w<size;i--,w++){
if(queen==chess[i][w])
return false;
}
return true;
}
}