八皇后问题算法
-
问题引入:在八行八列的格子上放8个皇后(棋子),使得任意两个皇后都攻击不到对方,即使得他们都不在同一行同一列和同一斜线上。
-
思路分析:
- 第一个皇后放在第一行第一列;
- 第二个皇后放在第二行第一列,判断是否满足,如果不满足,则继续放在第二列、第三列,依次放完所有列,找到合适的位置;
- 继续把第三个皇后放在第三行第一列、第二列....直到第8个皇后也能放在一个不冲突的位置,说明找到一个8皇后解了;
- 当找到正确解后,在栈回退到上一个栈时,就会开始回溯,即把第一个皇后放在第一列的所有正解都得到;
- 然后回头继续第一个皇后放在第二列,继续执行前面的所有步骤。
-
说明:
理论上应该创建一个二维数组表示棋盘,但是实际上可以通过算法,用一个一维数组就可以解决,如:
Array[8]={0,4,7,5,2,6,1,3};
数组的下标表示第几行,即第几个皇后,下标0表示第1一个皇后;数组的每一个值表示第i+1个皇后放在第i+1列。
-
核心方法:
- 方法1,将皇后的位置输出。
- 方法2,检查放置当前皇后是否冲突。
- 方法3,用于放置第n个皇后,使用了递归思想,select每一次递归时,进入到select中都由一个for循环,会由回溯。
-
代码实现
package com.guodaxia.recursion;
/**
* @ author Guo daXia
* @ create 2022/11/20
*/
public class Queue8 {
public static void main(String[] args) {
//创建当前类对象
Queue8 queue8= new Queue8();
queue8.select(0);//从第一个皇后开始
System.out.printf("一共有%d解法\n",count);
System.out.printf("一共判断冲突的次数%d次\n",judgeCount);
}
static int count =0;
static int judgeCount = 0;
//8个皇后
int max=8;
//数组保存正解
int[] array = new int[max];
//方法3,用于放置第n个皇后,使用了递归思想,select每一次递归时,进入到select中都由一个for循环,会由回溯
private void select(int n){
if (n==max){
//如果n=8,则8个皇后放好了
print();//打印
return;//结束
}
//依次放入皇后,需要判断是否冲突
for (int i = 0; i < max; i++) {//i代表对某行 列扫描
//第一个皇后固定在第一行第一列
array[n]=i;
//判断
if (judge(n)){//judge方法true,表示不冲突
//接下来放置n+1个皇后,递归
select(n+1);
}
//接下来是冲突,继续执行array[n]=i;即将第n个皇后放在本行中的后移一个位置
}
}
/**
* 方法2,检查放置当前皇后是否冲突
* @param n 表示第n个皇后
* @return 返回false,则冲突;返回true,则不冲突
*/
private boolean judge(int n){
judgeCount++;
for (int i = 0; i < n; i++) {
//情况1,判断是否同一列,array[i]==array[n]
//情况2,判断是否同一斜线上,行差==列差
//情况3,是否同一行,因为n代表第n个皇后,所以不会同一行
if (array[i]==array[n]||Math.abs(n-i)==Math.abs(array[n]-array[i])){
return false;
}
}
return true;
}
//方法1,将皇后的位置输出
private void print(){
count++;
for (int i = 0; i < array.length; i++) {
System.out.printf(array[i]+"");
}
System.out.println();
}
}
标签:int,问题,++,算法,冲突,皇后,array,select
From: https://www.cnblogs.com/container-simple/p/16909994.html