八皇后问题是一个以国际象棋为背景的问题:如何能够在 8×8 的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
则思路是:
(1)从第一行开始,从第一行第一列开始摆放,判断“后”是否安全。
(2)若安全则进入下一行,否则进入下一列。
(3)判断的方法是有三个方向:(3.1)左上角,(3.2)正上方,(3.2)右上方。
(4)若下一行八个位子都不可以则退回上一行进行上一行的调整。
(5)需要注意的是:程序只需要考虑那一行的事情,不必要考虑下一行的事。
核心代码:
#include <stdio.h>
#include "eightQueen.h"
void orderQueen(int (*chessboard)[ORDER], const int row) {
// 在当前行只需要考虑当前行!
// 若当前行行号已经是ORDER了,意味着,前面ORDER行已经成功!
static int count = 0; //只是定义使得输出个数的限定。
if (row >= ORDER) {
++count;
drawChessboard(chessboard);
} else {
int col;
for (col = 0; count < 23 && col < ORDER; col++) { // 尝试每一列
chessboard[row][col] = 1; // 放置皇后
if (isSafe(chessboard, row, col)) { // 若本行本列是安全的
orderQueen(chessboard, row + 1); // 放置下一行
}
chessboard[row][col] = 0; // 无论本行列是安全或者不安全的,
// 都需要去掉本位置的皇后!因为,下列需要放置一个皇后!
}
}
}
void drawChessboard(int (*chessboard)[ORDER]) { //输出最终的结果。
int row;
int col;
static int count = 0; //static(静态存储量)不随着函数运行结束而释放,将接着上一回的结果往下走。
printf("第%d个解:
", ++count);
for(row = 0; row < ORDER; row++) {
for(col = 0; col < ORDER; col++) {
printf("%2d", chessboard[row][col]);
}
printf("
");
}
}
boolean isSafe(int (*chessboard)[ORDER], const int row, const int col) {
int i;
int j;
for (i = row - 1, j = col - 1; i >= 0 && j >= 0; i--, j--) { //判断左上角是否安全!
if (chessboard[i][j] == 1) {
return FALSE;
}
}
for (i = row - 1, j = col; i >= 0; i--) { //判断上方是否是安全的!
if (chessboard[i][j] == 1) {
return FALSE;
}
}
for(i = row - 1, j = col + 1; i >= 0 && j < ORDER; i--, j++) { //判断右上角是否是安全的!
if (chessboard[i][j] == 1) {
return FALSE;
}
}
return TRUE;
}
主函数代码:
#include <stdio.h>
#include "./include/eightQueen.h;
int main() {
int chess[ORDER][ORDER] = { 0 };
orderQueen(chess, 0);
return 0;
}