八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
package recursion;
public class Queen {
//先定义一max表示皇后的数量
int max = 8;
//定义一个一维数据存放位置结果
int[] array = new int[max];
//统计有多少种解法
int count=0;
public static void main(String[] args) {
//测试
Queen queen = new Queen();
queen.check(0);
System.out.println(queen.count+"种解法");
}
//向棋盘中放置皇后
public void check(int n){
if (n==max){//n==8时,八个皇后已经放好,递归的出口
print();
return;
}
//依次放入皇后,并判断是否冲突
for (int i=0;i<max;i++){ //产生回溯的现象
//先把当前皇后放到该行的第一列
array[n]=i;
//判断当前放置第n个皇后到i列时是否发生冲突
if(judge(n)){//不冲突
//接着防止n+1个皇后,开始递归
check(n+1);
}
}
}
//判断皇后的位置是否冲突
/**
*
* @param n 表示第n个皇后
* @return
*/
public boolean judge(int n){
for (int i=0;i<n;i++){
//array[i]==array[n],表示判断第n个皇后和前n-1个皇后是否在同一列
//Math.abs(n-i)==Math.abs(array[n]-array[i]),表示判断第n个皇后和第i个皇后是否在同斜线(行-行的值等于列-列的绝对值)
if (array[i]==array[n]||Math.abs(n-i)==Math.abs(array[n]-array[i])){
return false;
}
}
return true;
}
//写一个方法输出皇后摆放的位置
public void print(){
count++;
for (int num:array) {
System.out.print(num+" ");
}
System.out.println();
}
}