问题表述为:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
public class Queen{
public static void main(String[] args){
Queenplace queen = new Queenplace();
queen.place(0);//下标从0开始
System.out.print("count= "+ queen.count);//记录有多少种摆法
}
}
class Queenplace{
int count = 0;//计数器
int arr[] = new int[8];
//思路分析:
//1.棋盘可以看做是一个8x8的二维数组
//我们这里创建一个1维数组来解决 下标i表示行号 arr[i]的数值表示列号
public void place(int n){//2.创建放置方法:接收放置皇后的个数,也就是第几个。因为下标从0开始,接收第一个数值为0,但表示第一个皇后
if(n==8){
print_();//满足条件 打印
return;//n=8则表示已经存在9个皇后 退出
}
for(int i= 0; i<8; i++){
arr[n] = i;//假设第1个棋子放在第1行第1列(坐标是 (0,0))
if(chick(n)){
place(n+1);//判断方法成立 则开始放置第二个棋子 n+1
}
}
}
private boolean chick(int n){//3.判断此处是否能够放置棋子的方法
//棋子不能在同一行,同一列,因为n每次递增,所以行不再比较
//arr[i]的值代表列
for(int i = 0; i<n; i++){//因为这里是比较棋子位的合理性,假设现在放置的是第2个棋子,那么现在只需要跟第一个棋子比较,如果是第n+1个棋子则表示与0-n个棋子依次比较,所以判断条件为:i<n
if(arr[i] == arr[n] || Math.abs(n-i) == Math.abs(arr[n]-arr[i])){
//arr[i]==arr[n]的解释:
//这里的arr[n]表示的是第n+1个棋子的列号 (参数int n 接收的是n+1)
//i从0开始遍历 arr[i]则表示第n+1个棋子之前的每个棋子占据的列号
//abs.Math(n-i) == abs.Math(arr[n]-arr[i])此行表示斜率的比较
//最下面还有图文说明
//因为游戏规则是 每个棋子之间 行,列,对角方向都不能在同一条直线
//如果 第 n+1 个棋子 所在行的每一个位置都满足if(arr[i] == arr[n] || abs.Math(n-i) == abs.Math(arr[n]-arr[i]))的条件
//则表示第n个棋子的位置有误 需要重新放置 第n+1个棋子因为最后一个位置满足条件进入这个if判断中 然后返回flase
// 此时回溯到place()方法中的for循环中 i++ 重新尝试
return false;
}
}
return true;//表示以上条件都没进入 则返回true 表示当前棋盘格可以放置
}
private void print_(){//打印方法
count++;
for(int i = 0; i<arr.length; i++){
System.out.print(arr[i]+" ");
}
System.out.println();
}
}