一、八皇后问题
八皇后问题:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。
下面的图片为八皇后问题的一种解法:
二、实现
在编写这个程序之前,我们先来思考几个问题:
1.棋盘怎么表达?
答:用二维数组来表示,并且,1表示有皇后,0表示无皇后。
2.如何判断当前位置(行、列)是安全的?
答:分别判断左上方斜线、正上方以及右上方斜线有无皇后。
3.第一行、第二行...第i行...第八行,皇后的摆放方法(程序)是否相同?
答:相同。
4.对于每一行,需要尝试每一个位置(列),判断其安全性。若安全,则继续下一行(递归)。
5.若本行的所有位置都尝试过了(无论成功与否),都要返回到上一行,继续尝试上一行未尝试完的位置(列)。
6.何时算找到一个解?
答:当尝试到第九行时,就找到了一个解,即:前八行各存在一个互不冲突的皇后。
下面给出具体实现的代码:
#include <stdio.h>
#include "mec.h"
#define WIDTH 8
boolean isSafe(boolean (*chessBoard)[WIDTH],int row,int col);
void showChess(boolean (*chessBoard)[WIDTH]);
void chess(boolean (*chessBoard)[WIDTH],int row);
void chess(boolean (*chessBoard)[WIDTH],int row){
int col;
if(row >= WIDTH){
showChess(chessBoard);
return;
}
for(col = 0;col < WIDTH;col ++){
if(isSafe(chessBoard,row,col)){
chessBoard[row][col] = TRUE;
chess(chessBoard,row + 1);
chessBoard[row][col] = FALSE;
}
}
}
void showChess(boolean (*chessBoard)[WIDTH]){
int row;
int col;
static int count = 0;
printf("第%d个:\n",++count);
for(row = 0;row < WIDTH; row++){
for(col = 0;col < WIDTH; col++){
printf("%5d",chessBoard[row][col]);
}
printf("\n");
}
}
boolean isSafe(boolean (*chessBoard)[WIDTH],int row,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 < WIDTH;i--,j++ ){
if(chessBoard[i][j] == 1){
return FALSE;
}
}
return TRUE;
}
int main(){
boolean chessBoard[WIDTH][WIDTH] = {0};
chess(chessBoard,0);
return 0;
}
代码执行部分结果如下(输出了92个解):
以上说法若有不足之处,还请指点!