1.问题介绍
八皇后问题是一个古老而著名的问题,是回溯算法和递归调用的典型案例。八皇后难题是要将八个皇后(Queen)放在棋盘上,任何两个皇后都不能互相攻击(即没有任意两个皇后是在同一行、同一列或者同一条对角线上),问一共有多少种摆法。
2.思路分析
- 第一个皇后先放在第一行第一列
- 第二个皇后放在第二行第一列,然后判断能否在该位置放皇后,如果不可以,则继续放下一列,直至找到一个合适的位置
- 继续放置第三个皇后,还是第一列、第二列…直到第8个皇后也能放在一个不能相互攻击的位置,就找到了一个正确解。
- 当得到一个正确解时,在栈回退到上一个栈时,就会开始回溯。即将第一个皇后放在第一列的所有解逐个得到。
- 完成以上步骤之后,将第一个皇后放在第二列,后面循环执行1, 2, 3, 4 步骤。

3.代码实现
package eightqueen;
public class eightqueen {
public static int MAXQUEEN = 8; //皇后个数,也是棋盘行列数
public static int[][] Board = new int[MAXQUEEN][MAXQUEEN]; //初始化棋盘
private static int count;
public static void startTest(Todo Todo, int row){
//第0列开始
for (int col = 0; col < MAXQUEEN; col++) {
//检查位置是否可以放棋子
if (Todo.checkBoard(MAXQUEEN, row, col, Board) == 1){
if (row == MAXQUEEN - 1){
count++;
}
//递归,向下一行前进
if (row < MAXQUEEN - 1){
startTest(Todo, ++row);
//回退上一个栈
--row;
}
}
//重新赋值为0,进行下一次判断
Board[row][col] = 0;
}
}
public static void main(String[] args) {
int row = 0;
Todo Todo1 = new Todo();
startTest(Todo1, row);
System.out.println("摆放一共有" + count + "种");
}
}
class Todo {
//定义横竖斜方向上是否有棋子
public static boolean flag = true;
//检查棋盘
public int checkBoard(int MAXQUEEN, int row, int col, int[][] Board){
//行方向上
for (int i = 0; i < MAXQUEEN; i++) {
if (Board[row][i] == 1){
return 0;
}
}
//列方向上
for (int i = 0; i < MAXQUEEN; i++) {
if (Board[i][col] == 1){
return 0;
}
}
//右下方向上
for (int i = row, j = col; i < MAXQUEEN && j < MAXQUEEN; i++, j++) {
if (Board[i][j] == 1){
return 0;
}
}
//左上方向上
for (int i = row, j = col; i >= 0 && j >= 0; i--, j--) {
if (Board[i][j] == 1){
return 0;
}
}
//左下方向上
for (int i = row, j = col; i < MAXQUEEN && j >= 0; i++, j--) {
if (Board[i][j] == 1){
return 0;
}
}
//右上方向上
for (int i = row, j = col; i >= 0 && j < MAXQUEEN; i--, j++) {
if (Board[i][j] == 1){
return 0;
}
}
if (flag) {
//此点符合要求,可以下
Board[row][col] = 1;
//如果已经到最后一行,则打印棋盘
// if (row == MAXQUEEN - 1){
// printBoard(MAXQUEEN, Board);
// }
//可以放
return 1;
}
return 0;
}
//打印棋盘
public static void printBoard(int MAXQUEEN, int[][] Board){
for (int i = 0; i < MAXQUEEN; i++) {
for (int j = 0; j < MAXQUEEN; j++){
System.out.print(Board[i][j] + " ");
}
System.out.println();
}
System.out.println("================");
}
}
4.最终结果

3769

被折叠的 条评论
为什么被折叠?



