首先我们看下什么是八皇后问题,看下官方回答。
{八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在8X8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。}
通俗的讲就是在8*8的棋盘上放8个棋子,使得不能有2个及其以上的棋子在同一行、同一列或者是同一条对角线上
现在设计一个程序,输出全部的解法及其解的总数;
#include <stdio.h>
#include <stdbool.h>
//全局变量数据初始化
int place[8] = { 0 };//第n个皇后所占位置的列号。
bool flag[8] = { 1,1,1,1,1,1,1,1 };//标志数组,表示第col列是否可站,1表示不冲突。
bool d1[15] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; //表示上三角形是否可占
bool d2[15] = { 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 }; // 表示下三角形是否可占
int number = 0; //用于统计解的数量(八皇后一共92个解)。
void print(); //注意不是stdio.h里面的printf函数,是自定义的函数。
void gernerate(int n); //其中n代表的是从第n+1行放置皇后。
int main()
{
gernerate(0); //这里的参数0代表从第1列放置皇后,有初始化的作用吧。
return 0; //主函数就是这么简单,果然是神才用递归,码农用迭代.
}
void gernerate(int n)
{
int col;
for (col = 0; col < 8; col++) //每个皇后有八种可能的列
{
if (flag[col] && d1[n - col + 7] && d2[n + col]) //判读位置是否冲突,注意这其中的条件是每个都要满足。
{
place[n] = col; // 在n行col列摆放皇后
flag[col] = false; //宣布占领第col列
d1[n - col + 7] = false; //占领两个对角线
d2[n + col] = false;
if (n < 7) //八个皇后没有摆完,递归摆放下一行里面的皇后
gernerate(n + 1);
else
print(); //n==7,皇后都摆完了,打印结果。
//回溯,考虑其他可行方案
flag[col] = true;
d1[n - col + 7] = true;
d2[n + col] = true;
}
}
}
void print()// 打印结果,第n个皇后所占位置的列号。
{
int col, i, j;
number++;
printf("No.%d\n", number);
//printf("八皇后的结果是:");
/*
for(col=0;col<8;col++)
printf("%d行%d列",col,place[col]);
printf("\n");
*/
int table[8][8] = { 0 };
for (col = 0; col < 8; col++)
table[col][place[col]] = 1;
for (i=0;i<8;i++)
{
for (j = 0; j < 8; j++)
{
printf("%d", table[i][j]);
}
printf("\n");
}
}
运行图