八皇后问题是十九世纪著名数学家高斯于1850年提出的。问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上。
可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。
不用二维数组,就用一个一维数组A[N],A[0]=x0表示第一列皇后在第x0行,依次A[i]=xi表示第i列皇后在xi行。
从第一列开始,挨着尝试,即A[0]从0到(N-1)去试。那么,第i列同样从0到(N-1)去验证摆在什么位置符合规则。
为了方便逻辑表达,把验证第i列皇后可以摆在xi的位置是否符合规则,做成一个单独的判断函数:
//A: address of A[];
//N: the length of A[],C语言传递数组地址,但是不知道数组的长度,因此单独传递数组的长度。
//npos: current position of A[]
int QueenCanPlace(int * A, int N, int npos, int nX)
{
int i=0, ok=1;
if((N>0)&&(npos>=0)&&(N>npos))
{
i=0;
while (i<npos)
{
if((nX==A[i])||((nX+i)==(npos+A[i]))||((A[i]+i)==(npos+nX)))
{
//once there is a collision, then set ok=false and exit
ok=0;
break;
}
i++;
}
}
return(ok);
}
还是基于递归,完成放置皇后的过程。
void hjd_QueenProblem(int * A, int N, int npos, FILE * fp)
{
if(npos<N)
{
for(A[npos]=0;A[npos]<N;A[npos]++)
{
if(QueenCanPlace(A, N, npos, A[npos])) //检验当前位置摆皇后是否与前npos-1列的已经摆好的皇后冲突
{
//如果在当前列,皇后能摆在当前位置,那么就继续尝试后面一列如何摆皇后。
hjd_QueenProblem(A, N, npos+1, fp);
}
}
}
else
{
//当摆完数组的最后一列后,npos会到N,说明A[]是一组符合要求的摆法,因此就打印输出结果
fprintf(fp, "\nThe answer is:\n");
for(int nY=0;nY<N;nY++)
{
for(int nX=0;nX<N;nX++)
{
if(A[nX]==nY)
fprintf(fp, "%d\t", 1);
else
fprintf(fp,"%d\t", 0);
}
fprintf(fp, "\n");
}
}
}
测试成功。