八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于 1848 年提出:在 8×8 格的国际象棋上摆放八个皇后,使其不能互相攻击,即:任意两个皇后都不能处于同一行、 同一列或同一斜线上,问有多少种摆法,答案是一共有92种摆法。
代码:
package demo;
public class EightQueue {
int max = 8; //表示有8个皇后
int[] array = new int[max]; //皇后放置位置
static int count= 0;
public static void main(String[] args) {
EightQueue queue = new EightQueue();
queue.check(0);
System.out.printf("共有%d解法",count);
}
//遍历皇后
private void print(){
count++;
for(int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
System.out.println();
}
//查看皇后是否满足不能互相攻击的要求,即前后皇后不在一列且不在一条斜线
//Math.abs(n-i)==Math.abs(array[n]-array[i]表示y=x直线,斜率为1,该线上所有点都在一条斜线上
private boolean judge(int n){
for(int i=0;i<n;i++){
if(array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n]- array[i])){
return false;
}
}
return true;
}
//放第n个皇后
private void check(int n){
if(n == max){ //一共8个皇后,从0开始,所以8就相当于n+1了
print();
return ;
}
//一次放入皇后,并且判断是否冲突
for(int i=0;i<max;i++){
array[n] = i;
if(judge(n)){
check(n+1);
}
}
}
}
其中需要注意的有以下几点:
1.array[i] == array[n] || Math.abs(n - i) == Math.abs(array[n]- array[i]),n表示第n个皇后,i表示第n个皇后之前的皇后,两者进行比较,当array[i] == array[n]表示两者在同一列。Math.abs(n - i) == Math.abs(array[n]- array[i])则表示斜率为1或-1的直线(可以举例子说明)。
结果:
共有92种解法。