每日算法练习——递归(八皇后问题:EightQueen)
程序员文章站
2022-05-25 11:43:17
...
知识补充:
八皇后问题
八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后,使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行、纵行或斜线上。
摘自wiki百科:https://zh.wikipedia.org/wiki/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98
C语言代码实现:
#include <stdio.h>
#include <stdlib.h>
int count =0; // 计数
// 判断危险
int notDanger(int row, int j , int (*chess)[8] )
{
int i,k,flag=1;
// 判断列方向,
for(i=0; i<8; i++)
{
if(i!=row) //非本皇后(棋子)的位置
{
if(*(*(chess+i)+j)!=0)
{
flag = 0;
return flag;
}
}
}
// 因为是按行放棋子,每行最多一个棋子,所以不需要判断行方向
// 左上方向
for(i=row-1,k=j-1; i>=0&&k>=0; i--,k--)
{
if(*(*(chess+i)+k)!=0)
{
flag = 0;
return flag;
}
}
// 右下方向
for(i=row+1,k=j+1; i<8&&k<8; i++,k++)
{
if(*(*(chess+i)+k)!=0)
{
flag = 0;
return flag;
}
}
// 右上方向
for(i=row-1,k=j+1; i>=0&&k<8; i--,k++)
{
if(*(*(chess+i)+k)!=0)
{
flag = 0;
return flag;
}
}
// 左下方向
for(i=row+1,k=j-1; i<8&&k>=0; i++,k--)
{
if(*(*(chess+i)+k)!=0)
{
flag = 0;
return flag;
}
}
// 如果上述几个危险检查都通过了返回flag=1
return flag;
}
// 参数 : 第row行 共n列,
void EightQueen(int row, int n,int (*chess)[8])
{
int chess2[8][8],i,j;
for(i=0; i<8; i++)
{
for(j=0; j<8; j++)
{
chess2[i][j] = chess[i][j];
}
}
if( row == 8 )
{
printf("第 %d 种\n",++count);
for(i=0; i<8; i++)
{
for(j=0; j<8; j++)
{
printf("%d ",*(*(chess2+i)+j));
}
printf("\n");
}
}
else
{
for(j=0; j<n; j++)
{
if(notDanger(row, j, chess)) //判断第row行第j列的位置是否危险
{
for(i=0;i<8;i++) // 如果不危险,先整行置0,再将第j列的位置置1;
{
*(*(chess2+row)+i) = 0;
}
*(*(chess2+row)+j) = 1;
EightQueen(row+1, n, chess2);
}
}
}
}
int main()
{
int chess[8][8],i,j;
for(i=0;i<8;i++)
{
for(j=0;j<8;j++)
{
chess[i][j]=0;
}
}
// 按行放棋子,从第0行开始
EightQueen(0,8,chess);
printf("总共有 %d 种解决方法!!\n",count);
return 0;
}
wiki百科代码C语言:
简直妙的不行:
#include <stdio.h>
#define QUEENS 8 /*皇后数量*/
#define IS_OUTPUT 1 /*(IS_OUTPUT=0 or 1),Output用于选择是否输出具体解,为1输出,为0不输出*/
int A[QUEENS], B[QUEENS * 3 + 1], C[QUEENS * 3 + 1], k[QUEENS + 1][QUEENS + 1];
int inc, *a = &A[QUEENS], *b = &B[QUEENS], *c = &C[QUEENS];
void lay(int i)
{
int j = 0, t, u;
while (++j <= QUEENS)
if (a[j] + b[j - i] + c[j + i] == 0)
{
k[i][j] = a[j] = b[j - i] = c[j + i] = 1;
if (i < QUEENS)
lay(i + 1);
else
{
++inc;
if (IS_OUTPUT)
{
for (printf("(%d)\n", inc), u = QUEENS + 1; --u; printf("\n"))
for (t = QUEENS + 1; --t; )
k[t][u] ? printf("Q ") : printf("+ ");
printf("\n\n\n");
}
}
a[j] = b[j - i] = c[j + i] = k[i][j] = 0;
}
}
int main(void)
{
lay(1);
printf("%d皇后共计%d个解", QUEENS, inc);
getchar();
return 0;
}