正方形棋盘, 皇后的垂直、水平、对角线方向上 不能有其他皇后。
在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法
/**
* @author :PangTiemin
* @date :Created in 2021/7/11 11:08
* @description: 皇后的垂直、水平、对角线方向上 不能有其他皇后
* @modified By:
*/
public class Queen {
//方法个数
private static int num =0;
//皇后个数
private static final int MAXQUEEN=8;
//每一列皇后所在的行索引
private static int[]col=new int[8];
//填第n列的皇后
public void getCount(int n){
//当前n列,第几行不能放皇后,true表示不能放
boolean[] rows = new boolean[MAXQUEEN];
//遍历n列之前所有列,找到不允许放的位置
for (int m=0;m<n;m++){
//水平方向不能放
rows[col[m]]=true;
//正斜方向
int d = n-m;
//棋盘是正方形,正斜负斜都是按正方形算
if (col[m]-d>=0){
//说明 m列皇后位置的正斜方向 与n列相交处没有超过棋盘边缘
rows[col[m]-d]=true;
}
//负斜方向
if (col[m]+d<MAXQUEEN){
rows[col[m]+d]=true;
}
}
for (int i=0;i<MAXQUEEN;i++){
if (!rows[i]){
//当前列可以放皇后的位置i,但此列还可能有其他位置;
// 先按这个i位置计算下一列,直到找到n列皇后放在i位的后续列所有方案,在回到n列把皇后放在剩余位置
col[n]=i;
//回溯关键,如果当前列能放皇后且不是最后一列,就继续找;
//如果当前列没有皇后的位置(for循环执行结束),说明方案错误,会递归结束回到上一列,把上一列的皇后换个位置
//如果当前列是最后一列,且有位置,说明找到方案,输出方案后,看最后一列是否有其他位置能放,没有就回到上一列继续找其他方案
if (n<MAXQUEEN-1){
getCount(n+1);
} else {
//找到一套解决方案
num++;
System.out.println("第"+num+"套方案");
for (int r=0;r<MAXQUEEN;r++){
for (int c=0;c<MAXQUEEN;c++){
if (col[c]==r){
System.out.print(1+" ");
}else {
System.out.print(0+" ");
}
}
System.out.println();
}
}
}
}
}
public static void main(String[] args) {
Queen queen = new Queen();
queen.getCount(0);
}
}