八皇后问题(英文:Eight queens):
问题表述:在8×8格的国际象棋上摆放8个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。
代码思路:
1.第一个皇后放在第一行第一列
2.第二个皇后放在第二行第一列,然后判断是否会有冲突,如果有冲突的话,继续放在第二列、第三列,把所有的列找完,直到找到一个合适的。
3.继续放第三个皇后,直到放置完第八个皇后,就算是找到了一个正确解。
4.当找到一个正确解时,栈回退到上一个栈,就会开始回溯,即将第一个皇后,放在第一列的正确解全部得到,
5.回头继续将第一个皇后放在第二列,依次循环执行1、2、3、4步
**tips:**理论上要用一个二维数组表示棋盘,实际上一维数组就可以,因为下标可以用来表示第几个皇后,数组的值表示放在第几个位置。
代码实现
package com.atguigu.recursion;
public class Queue8 {
int max = 8;
static int count = 0;
static int judgecount = 0;
int[] array = new int[max];
public static void main(String[] args) {
//测试一把
Queue8 queue8 = new Queue8();
queue8.check(0);
System.out.printf("一共有%d种解法\n", count);
System.out.printf("一共判断冲突的次数有%d次", judgecount);
}
//编写一个方法,放置第n个皇后
private void check(int n){
if(n == max){//八个皇后已经放好了
print();
count++;
return;
}
for(int i=0;i<max;i++){
//先把当前这个皇后,第n个,放到该行的第一列
array[n] = i;
if(judge(n)){
check(n+1);
}
//如果冲突,就继续执行array[n] = i,即将第n个皇后,
// 放置在本行后移的一个位置
}
}
//当我们放置第n个皇后时,就去检测该皇后是否和前面已经摆放的皇后冲突
private boolean judge(int n){
judgecount++;
//array[i] == array[n]表示在同一列,Math.abs(n-i)==Math.abs(array[n]-array[i])表示在对角线上
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;
}
//写一个方法,将皇后摆放的位置输出
private void print(){
for(int i = 0;i<array.length;i++){
System.out.print(array[i]+"");
}
System.out.println();
}
}