/* 程序问题注释开始
-
程序的版权和版本声明部分
-
Copyright © 2020,湖南工程职业技术学院信息工程学院学生
-
文件名称: 蓝桥杯赛题
-
作 者: 李 斌
-
完成日期: 2020 年 04 月 19日
-
对任务及求解方法的描述部分
-
问题描述
给定一个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 -
程序问题注释结束
*/
//2n皇后问题
package twoN皇后问题;
import java.util.*;
public class Main {
//记录总数
public static int count;
//棋盘大小
public static int size;
//定义的棋盘
public static int chess[][];
public static void main(String[] args)
{
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();
}
}
put(0,2);
System.out.println(count);
}
//定义将皇后棋放入棋盘的方法 2表示白皇后 3表示黑皇后
// 1.先判断棋盘位置是否为1 因为只有1才能放棋
// 2.判断棋子是否不满足处于同一行 同一列 同一对角线
// 3.先放白皇后棋,当白皇后棋放好后,再放置黑色棋
//row 表示行 chess表示皇后棋
public static void put(int row,int queen )
{
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 static 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;
}
}
运行结果1:
运行结果2: