八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
#include <iostream>
using namespace std;
#define N 8
using Pos = struct _tag_pos {
int ios;
int jos;
};
static char board[N + 2][N + 2];
/*设置对角线,同一列的偏移量*/
static Pos pos[] = { {-1,-1},{-1,0},{-1,+1} };
void display() {
for (int i = 0; i < N + 2; ++i ) {
for (int j = 0; j < N + 2; ++j ) {
cout << board[i][j];
}
cout << endl;
}
}
void init() {
for (int i = 0; i < N + 2; ++i ) {
board[0][i] = '#';
board[N + 1][i] = '#';
board[i][0] = '#';
board[i][N + 1] = '#';
}
for (int i = 0; i < N; ++i ) {
for (int j = 0; j < N; ++j ) {
board[i+1][j+1] = ' ';
}
}
}
/*检查这个(i,j)点能否放下棋子*/
bool check( int i , int j ) {
bool flag = true ;
for (int p = 0; p < 3; ++p ) {
int ni = i;
int nj = j;
while ( flag && (board[ni][nj]!='#') ) {
ni = ni + pos[p].ios;
nj = nj + pos[p].jos;
flag = flag && (board[ni][nj]!='*');
}
}
return flag ;
}
/*查看第i行的某一列j能否放下棋子*/
void find( int i ) {
if ( i>N ) {
display();
getchar();
}
else {
/*假设现在在第i行,就从这一行的头到尾依次检测是否能放下棋子*/
for (int j = 1; j <= N; ++j ) {
if ( check(i,j) ) {
board[i][j] = '*';
find(i+1);/*如果第i行能放下棋子,就查看第i+1行能否放下棋子*/
board[i][j] = ' ';
}
}
}
}
int main( int argc , char *argv[] ) {
init();
find( 1 );
return 0;
}