八皇后问题简述:即求8*8的棋盘的所有合法布局,所为合法布局就是:棋盘上共摆放八个棋子,使得每两个棋子都不在棋盘上的同一行、或者同一列、或同一对角线。
在查找所有情况过程中利用回溯法,回溯法的基本做法是搜索,或是一种组织得井井有条的,能避免不必要搜索的穷举式搜索法。这种方法适用于解一些组合数相当大的问题。
在遍历的过程中,检查是否符合规定,即a[k]==a[i] || abs(a[k],a[i])==abs(i,k),将符合规定的结果输出即可。
我的代码中输出了每种情况的摆放方式,并在最后输出了共有多少种情况。代码实现如下:
#include "stdio.h"
#include "stdlib.h"
#define n 9
int count=0;
int a[n];
int abs(int a,int b)
{if(a>b) return a-b; else return b-a;}
//*************检查函数****************
int check(int a[n],int k)
{int i,flag=1;for(i=1;i<k;i++)
{if(a[k]==a[i]||abs(a[k],a[i])==abs(i,k))
{flag=0; break; }} return flag;}
//**************求解八皇后****************
void Queens(int k)
{ int i,j;
if (k>=n) {
for(j=1;j<n;j++)
printf("(%d,%d) ",j,a[j]);
printf("\n");
count++;
for(i=1;i<n;i++) {
for(j=1;j<n;j++)
if(a[i]==j)
printf("%d ",a[i]);
else printf("0 ");
printf("\n");
}
} // 即表示最后一个皇后摆放完毕,输出结果;
else {
for(i=1 ; i<n; i++) //枚举K个皇后所有可能的路径
{ a[k]=i;//依次从列顶端开始搜索,一直到列底端,直到找到合适位置,如果未找到,自动返回上层递归
if (check(a,k)) //满足限界函数和约束条件,不冲突
Queens (k+1); //递归摆放下一个皇后
}
}
}
int main()
{
int k;
Queens(1);
printf("\n满足条件的有%d组\n",count);
return 0;
}
运行结果的部分截图如下: