问题描述:
- 要在8*8的国际象棋棋盘中放置8个皇后,使任意两个皇后都不能互相吃掉;
- 国际象棋的规则是皇后能吃掉同一行、同一列、同一对角线的棋子;
解题思路:
该题运用到递归回溯,难点在于判断皇后的摆放是否符合题目要求并获取最多解法。
如图所示,在 row=0时,即从第一行第一列位置放置皇后时不受到其他皇后位置的影响(通过notDanger的判断),通过后再次调用EightQueen进行递归并使 row+1(皇后的放置推到下一行),以此类推,如果皇后的放置在该行内找到合适的位置则可以继续调用EightQueen(row+1)直至遍历八行后打印输出;否则将执行清零操作,并控制前一行皇后位置通过for循环列数+1,即调整前一位皇后位置,重复上述步骤。
运行结果如下:
代码如下:
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
typedef int Status;
int count = 0; // 解法
int chess[8][8] = {0};
Status notDanger(int row, int col)
{
int i,j;
// 判断列方向
for(i=0; i<8; i++)
{
if(chess[i][col]==1)
{
return 0;
}
}
// 判断左对角线
for(i=row,j=col; i>=0&&j>=0; i--,j--)
{
if(chess[i][j]==1)
{
return 0;
}
}
// 判断右对角线
for(i=row,j=col; i>=0&&j<8; i--,j++)
{
if(chess[i][j]==1)
{
return 0;
}
}
return 1;
}
void PrintList() // 打印结果
{
int row,col;
printf("第 %d 种解法\n",count+1);
for(row=0; row<8; row++)
{
for(col=0; col<8; col++)
{
if(chess[row][col]==1)
{
printf("×");
}
else
{
printf("口");
}
}
printf("\n");
}
printf("\n");
}
void EightQueen(int row)
{
int col;
if(row==8) // 如果遍历八行
{
PrintList(); // 打印列表
count++;
return ;
}
for(col=0; col<8; col++) // 递归回溯
{
if(notDanger(row, col)) // 判断是否危险
{
chess[row][col] = 1;
EightQueen(row+1);
chess[row][col] = 0; // 数据清零
}
}
}
int main()
{
EightQueen(0);
// 调用函数
printf("共有 %d 种解决方法!\n", count);
return 0;
}