懒猫老师八皇后视频:
懒猫老师-C语言-递归函数-八皇后问题(搜索,回溯)_哔哩哔哩_bilibili
import org.junit.Test;
import java.util.Arrays;
public class HelloQueen {
private int[] place = new int[8]; // 表示棋盘的一行
private boolean[] flag = new boolean[8]; // 纪录列的占用情况
private boolean[] d1 = new boolean[15]; // 纪录主对角线的占用情况
private boolean[] d2 = new boolean[15]; // 纪录副对角线的占用情况
private int count; // 用于纪录成功放置8皇后的次数
public HelloQueen() {
// 初始化数组的值
Arrays.fill(flag,true);
Arrays.fill(d1,true);
Arrays.fill(d2,true);
}
public void putQueen(int row){ // row表示当前行
for(int col = 0; col < 8; col++){ // 从第row的第1列向第8列遍历
if(flag[col] && d1[row-col+7] && d2[row+col]){
// 放置皇后
place[row] = col;
// 标记占用
flag[col] = false; // col列被占用
d1[row-col+7] = false; // 对应主对角线被占用
d2[row+col] = false; // 对应副对角线被占用
// 当row < 7 时
if(row < 7){ // 递归调用
putQueen(row+1); // 继续放置下一行皇后
} else { // 当row == 7 时, 递归终止
print(); // 输出本次皇后的摆放位置
}
// 回溯,当代码执行到此处有2种情况:
// 1. 从putQueen()递归方法中返回, 并且在后续递归中未能找到合适位置, 则需要将row行,col列的所有标记清除, 并继续遍历row行col+1列。
// 2. 已经成功放置8个皇后, 即进入else语句, 同样也需要将row行,col列的所有标记清除,并返回至上一级方法调用处, 如果上一行皇后的位置不在最后一列,则会继续往后查找其它情况。如果上一行皇后在最后列, 则会继续返回上一行重复操作。
// 清除标记
flag[col] = true;
d1[row-col+7] = true;
d2[row+col] = true;
}
}
}
// 输出本次皇后摆放位置
public void print(){
// 纪录次数
System.out.println("第" + (++count) + "次八皇后的排列方式: ");
// 利用place数组中存放的信息, 还原为一个二维数组
// 'Q'表示皇后, '.' 表示空
char[][] chessBoard = new char[8][8];
for(int i = 0; i < 8; i++){
Arrays.fill(chessBoard[i],'.');
// 将第i行的第place[i]列置为Q
chessBoard[i][place[i]] = 'Q';
}
// 遍历
for(char[] chars : chessBoard){
for(char chess : chars){
System.out.print(chess + "\t");
}
System.out.println();
}
}
@Test
public void testQueen(){
putQueen(0); // 从第1行开始
}
}