八皇后问题的难点在于它的回溯思想。说白了就是挨着试,假设第一行的皇后在(0, 0)位置,然后在第二行从第一列开始挨着试,直到找到合适的位置,然后第三行继续,当发现第三没有位置可以放时,就需要回溯,即清除第三行和第二行的操作,第一行换下一个位置继续尝试,大概就是这么个思路,所以在回溯的时候要将该行的皇后搬走,因为他放在这里是个错误的决定。
然后继续下一个位置,确定第一行就开始第二行,确定第二行就开始第三行,以此类推,不合适就回溯(推翻重来),直到最后一行皇后放置好了,就可以将这种方案打印出来,然后从最后一行开始回溯尝试其他位置。
package com.yc.algorithm.recursion;
/**
* 八皇后问题
* @author yc
*/
public class EightQueen {
//用来计数符合条件的总次数
private static int count;
//模拟棋盘
private static int[][] chess = new int[8][8];
public static void main(String[] args) {
System.out.println("八皇后问题求解开始 : ");
findQueen(0);
System.out.println("共有【" + count + "】种解法!!!");
}
/**
* 安放皇后
*/
private static void findQueen(int row) {
if (row > 7) {//找到方案,打印
count++;
print(chess);
return;
}
for (int col = 0; col < 8; col++) {
if (check(row, col)) { //检测该点是否合适
chess[row][col] = 1; //安放皇后
findQueen(row + 1); //寻找下一行皇后位置
chess[row][col] = 0; //该方案不合适,回溯,清空本次皇后位置。
}
}
}
/**
* 判断此处是否合适安放皇后。
* 只需判断当前列,左上角,右上角即可,因为后边位置还没有放置,不会存在皇后。
* @param i
* @param j
* @return
*/
private static boolean check(int i, int j) {
//检测列是否合适
for (int m = 0; m < 8; m++) {
if (chess[m][j] == 1) {
return false;
}
}
//检测左上方是否合适
for (int m = i - 1, n = j - 1; m >= 0 && n >= 0; m--, n--) {
if (chess[m][n] == 1) {
return false;
}
}
//检测右上方是否合适
for (int m = i - 1, n = j + 1; m >= 0 && n < 8; m--, n++) {
if (chess[m][n] == 1) {
return false;
}
}
return true;
}
/**
* 打印符合条件的棋盘
* @param chess
*/
private static void print(int[][] chess) {
System.out.println("第" + count + "次方案 : ");
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
System.out.print(chess[i][j] + " ");
}
System.out.println();
}
System.out.println();
}
}
输出如下(结果太多,列举一二):
八皇后问题求解开始 :
第1次方案 :
1 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
第2次方案 :
1 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 0 1 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
第3次方案 :
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0
第4次方案 :
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
... ...
第92次方案 :
0 0 0 0 0 0 0 1
0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0
0 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
共有【92】种解法!!!