Boolean:EightQueens(Boolean:spot_taken[,],Integer:num_queens_positioned)
//spot_taken[,]是一个二维数组,用来标识棋盘。
//考察这个候选方案(即现在的棋盘)是否已经不合理
If(Not IsLegal(spot_taken)) Then Return false
//考察是否已经将皇后摆好
If(num_queens_positioned == 8) Then Return true
//如果此步合理,但皇后还没摆好
//进行扩展部分解
//定位到棋盘具体位置
For row = 0 To 7
For col = 0 to 7
//判断当前位置有没有皇后
If(!spot_taken[row,col])
Then
//将皇后摆上该位置
spot_taken[row,col] == true
//递归判断这个棋盘是否合理,不合理就返回上一层,合理就继续下一层
//如果第二层Return true,那么第一层也会回到这里Return true
If(EightQueens(spot_taken,num_queens_positioned+1)) Then Return true
//如果棋盘不合理,就将取出该皇后
spot_taken[row,col] == false
End If
Next col
Next row
//到这一步,当前棋盘没有摆法正确,也就是没有可行解
Return false
Next EightQueens
这里的IsLeagl方法用来考察
《一线大厂Java面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》
【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享
这个方案,也就是当前棋盘种是否符合规则,也就是是否有皇后出现在同一行、同一列、或同一斜线上。
如果这不是一个完整解,程序会遍历所有行和所有列,如果这个位置没有皇后就将皇后放上去,然后递归调用检查当前棋盘是否合理,如果合理,就会在下一层递归继续扩展。。。。
直到最后一层递归调用返回为true,那么程序就会找到一组完整解,所有的递归调用都会返回true(不会走下一步的取出皇后)
如果某一层返回为false,那么就会走下一步的取出皇后,讨论下一个可能解。
Java实现
/**
-
@Author: Ember
-
@Date: 2021/3/13 16:32
-
@Description: 八皇后问题
*/
public class EightQueens {
/**
-
使用二维数组代表棋盘
-
1:代表已经摆了皇后
-
0:代表未摆放
*/
private int[][] spotTaken;
/**
- 标识摆第几个皇后
*/
private int numQueen;
/**
- 八皇后满足条件
*/
private final int EIGHT_QUEEN = 8;
/**
- 初始化棋盘和第几个皇后
*/
public EightQueens() {
//对棋盘进行初始化
spotTaken = new int[8][8];
for (int i = 0; i < spotTaken.length; i++) {
for (int j = 0; j < spotTaken.length; j++) {
spotTaken[i][j] = 0;
}
}
numQueen = 0;
}
/**
-
检验新摆的皇后是否合理
-
@param row
-
@param column
-
@return
*/
private boolean isLegal(int row,int column){
//检查行列
for (int i = 0; i < this.spotTaken.length; i++) {
//检查行
if(i != column && this.spotTaken[row][i] == 1){
return false;
}
//检查列
if (i != row && this.spotTaken[i][column] == 1){
return false;
}
}
//检查主对角线下方
for(int i = row,j = column; i < spotTaken.length && j < spotTaken.length;i++,j++){
//检查主对角线的下方
if(i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
//检查主对角线上方
for(int i = row,j = column; i >= 0 && j >= 0;i–,j–){
if(i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
//检查副对角线下方
for(int i = row,j = column;i < spotTaken.length && j >= 0;i++,j–){
if( i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
//检查副对角线上方
for(int i = row,j = column;i >= 0 && j < spotTaken.length;i–,j++){
if( i != row && j != column && spotTaken[i][j] == 1){
return false;
}
}
return true;
}
/**
-
检查皇后是否可以放在这个位置
-
@param row
-
@param column
-
@return
*/
private boolean isCanPut(int row,int column){
return this.spotTaken[row][column] != 1;