package com.xurong.recursion;
public class EightQuee {
//棋盘格子的范围,以及皇后的数量
static final int MAX_NUM = 8;
//二维数组作为棋盘
//int数组,默认初始化值为0,当符合皇后放置是,对应元素改为1
int chessBoard[][] = new int[MAX_NUM][MAX_NUM];
public static void main(String[] args){
EightQuee eightQuee = new EightQuee();
eightQuee.settleQueen(0);
eightQuee.printChessBoard();
}
/**
*输出皇后走完的棋盘
*/
private void printChessBoard() {
for (int i=0; i<MAX_NUM; i++) {
for (int j=0; j<MAX_NUM; j++) {
System.out.print(chessBoard[i][j]+" ");
}
System.out.println();
}
}
/**
* 进行递归回溯,完成对八皇后问题一个解的赋值
* @param x 代表行,也代表第x个皇后(x从0到7)
* @return
*/
boolean settleQueen(int x) {
//行数超过8,已经找到答案
if (x == MAX_NUM) {
return true;
}
//遍历当前行,逐一格子验证
for (int i = 0; i < MAX_NUM; i++) {
//为当前行清0,以免在回溯的时候出现脏数据
for(int y = 0; y < MAX_NUM; y++) {
chessBoard[x][y] = 0;
}
//检查是否符合规则,如果符合规则,更改元素值并进一步递归
if (check(x,i)) {
chessBoard[x][i] = 1;
//递归如果返回true,说明下层已经找到解法,无需循环
if (settleQueen(x + 1)) {//递归应用于此处
return true;
}
}
}
return false;
}
/**
* 检查落点是否符合规则
* @param x 横坐标
* @param y 纵坐标
* @return
*/
boolean check(int x,int y) {
for(int i = 0; i < x; i++) {
//检查纵向
if (chessBoard[i][y] == 1) {
return false;
}
//检查左倾斜-->此处采用的思路是从上往下放置皇后(注意:边界值依据纵坐标来限定),从左往右略微不同(注意边界限定)
if(y+1+i < MAX_NUM && chessBoard[x-1-i][y+1+i] == 1) {
return false;
}
//检查右倾斜
if (y-1-i >= 0 && chessBoard[x-1-i][y-1-i] == 1) {
return false;
}
}
return true;
}
}
输出结果:
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