八皇后问题:皇后可以在横、竖、斜线上不限步数地吃掉其他棋子。如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!
八皇后问题有92种解
算法思路:
1、初始化i=1;
2、初始化j=1;
3、从第i行开始,恢复(i,j)位置的可走性(这样保证所有的结果都能求出):
a、位置j可放皇后标记位置(i, j),i++,转步骤2;
b、位置j不可放,j++,转步骤a;
c、当j>8时,回溯到上一步,i--,转步骤3。
4、结束,显示结果
代码实现:
#include <stdio.h>
#define N 8
typedef struct Pos
{
int ipos;
int jpos;
}Pos;
static char board[N+2][N+2]; //加2的原因是为了画边界
static Pos pos[] = { {-1,-1}, {-1,0}, {-1,1} };
static int count = 0; //用于统计解决方法的个数
void init()
{
int i=0;
int j=0;
for( j = 0; j < N+2; j++ )
{
board[0][j] = '#';
board[j][0] = '#';
board[N+1][j] = '#';
board[j][N+1] = '#';
}
for(i = 0; i < N; i++)
for(j = 0; j<N; j++)
board[i+1][j+1] = ' ';
}
void display()
{
int i = 0;
int j = 0;
for(i = 0; i <N+2; i++)
{
for(j = 0; j<N+2; j++)
printf("%c", board[i][j]);
printf("\n");
}
}
int Check(int i, int j)
{
int = 1;
int p = 0;
for( p = 0; p < 3; p++ )
{
int ni = i;
int nj = j;
while( ret && ( board[ni][nj] != '#' ) ) //不能写成0<ni && 0<nj 这样会使解的数目减少
{
ni += pos[p].ipos;
nj += pos[p].jpos;
if( board[ni][nj] == '*' )
ret = 0;
}
}
return ret;
}
void find(int i) //这样做是为了能够递归回溯,得到所有的求解方法
{
int j = 0;
//边界条件
if(i>N)
{
count++;
printf("Solution%d\n", count);
display();
}
else
for( j = 1; j <= N; j++ )
if( Check(i, j) )
{
board[i][j] = '*';
find(i+1);
board[i][j] = ' '; //这样做使得程序能够回溯求解正确解
}
}
int main()
{
init();
find(1);
return 0;
}