八皇后问题
八皇后问题是指任何两个皇后不能处在同一行、同一列、同一斜线上,问有多少种摆法。
思路分析:
当取得一个正确解的时候,他会把第一个皇后所在位置的所有解先求出来。比如说:他会把(1,1)这个位置中皇后所有的解求出来。
编程分析
正常编程是需要用二维数组来代表棋盘,但是也可以使用一维数据进行编程。比如ints[0] = 0就可以代表第一行第一列,ints[a][b]代表的第a+1行,b+1列。
/**
* FileName: Queue8
*
* @Author:luguobao Date: 2020/4/2010:22
* Description:
* History:
* <author> <time> <version> <desc>
* 作者姓名 修改时间 版本号 描述
*/
public class Queue8 {
static int max = 8;
static int[] ints = new int[max];
static int count = 0;
public static void main(String[] args) {
put(0);
System.out.println("解决方式有" + count);
}
/**
* 对棋盘中元素进行输出
*/
public static void out(){
count++;
for (int i = 0; i < max; i++) {
System.out.print(ints[i]);
}
System.out.println();
}
/**
*
* @param n 第n个皇后是不是和之前的皇后有冲突。
* 第n个皇后肯定是在第n行的。
* @return
*/
public static boolean judge(int n){
for (int i = 0; i < n; i++) {
//判断列是否相等,或者是否在斜线上
if(ints[i] == ints[n] || n-i == Math.abs(ints[n] - ints[i])){
return false;
}
}//当第n个皇后与之前皇后都不冲突的时候,才返回true。
return true;
}
/**
*
* @param n 对第n个皇后进行放置,注意因为ints[n],n是从0开始的。
* 在调用这个方法的时候,需要把他从0开始调用。
* @return
*/
public static void put(int n){
if(n == max){
//如果n=8,代表,数组中已经有8个数了,则将其结果进行输出。
out();
return;
}
for (int i = 0; i < max; i++) {
//从第一列开始放置
ints[n] = i;
//如果放在i列不冲突的话,再放置第二个
if(judge(n)){
put(n+1);
}
//如果冲突的话,再换一列再试。
}
}
}
结果输出为:
对put()方法进行分析:
/**
*
* @param n 对第n个皇后进行放置,注意因为ints[n],n是从0开始的。
* 在调用这个方法的时候,需要把他从0开始调用。
* @return
*/
public static void put(int n){
if(n == max){
//如果n=8,代表,数组中已经有8个数了,则将其结果进行输出。
out();
return;
}
for (int i = 0; i < max; i++) {
//从第一列开始放置
ints[n] = i;
//如果放在i列不冲突的话,再放置第二个
if(judge(n)){
put(n+1);
}
//如果冲突的话,再换一列再试。
}
}
由于有for循环,故就算它找到了一种方法,比如最后一种73025164 它还是会往后面判断730251645。故其实他的判断次数有15000多次。但是,如果,第一次放7位置,第二次放的也是7位置就不会向后面判断了因为本身judge就返回false,故不会执行put(3)了,这就是为什么判断不是8的8次方的原因。但是,如果第一次放0位置,第二次放2、3、4、5、6、7都是可以判断成功的,则她们都会相应的进行执行,不会拉下。直到输出,或者执行不了。这就是递归的回溯用法。