八皇后问题解答:
解法1-非递归算法:
算法分析:
对于八个皇后的位置,可以看成一个由1,2,3,4,5,6,7,8组成的八位数,这个八位数的第n位的数字代表的是第n行皇后坐在的列数,有排列组合的可以组成这个数范围为12345678~87654321,那么只要把遍历下去,只要把符合题意的输出即可。
不过在此处有一个可以改进的地方就是可以有数学证明我们有1~8组成的数是一定可以被9整除的,所以我们的步长可以调整到9.
代码实现:
#include<stdio.h>
#include<math.h>
void main()
{
inta[9],b[9],i,j,flag_1=1,flag_2=1;
intcount=0; //解的个数
longint m;
printf("\t八皇后问题\n\n");
for(m=12345678;m<=87654321;m+=9)//步长是9
{
for(i=0;i<9;i++) //初始化数组或清零
{
a[i]=0;
b[i]=0;
}
j=8;
while(m>0) //分离整数
{
a[j]=m%10;
b[a[j]]=1;
m=m/10;
j--;
}
for(i=1;i<9;i++) //判断是否同列
if(b[i]!=1)
flag_1=0;
for(i=1;i<8;++i)
for(j=i+1;j<9;++j)
if((j-i)==abs(a[i]-a[j]))
flag_2=0;
if((flag_1==0)||(flag_2==0))
continue;
printf("第%d个解是:\n\t",++count);
for(i=1;i<9;i++) //输出解
printf("(%d,%d)",i,a[i]);
printf("\n");
}
}
解法2-递归算法
算法分析:
代码实现:
#include<stdio.h>
#include<math.h>
#define N 20
int row[N+1]; //存放皇后所在的行号
int count=0; //解的个数
int flag=0; //判断是否有解
//输出解
void print(int n)
{
inti;
++count;
flag=1;
printf("第%d个解:\n\t",count);
for(i=1;i<=n;i++)
printf("(%d,%d)",row[i],i);
printf("\n");
}
//判断在i行k列放皇后是否合法
int judge(int i,int k)
{
intm;
for(m=1;m<k;m++)
if(i==row[m]||(abs(m-k)==abs(row[m]-i)))
return0;
return1;
}
//放皇后
void place(int k,int n)
{
inti,flag=0;
if(k>n)
print(n);
else
for(i=1;i<=n;i++)
if(judge(i,k))
{
row[k]=i;
place(k+1,n);
}
}
//主函数
void main()
{
intn;
printf("\t经典算法-八皇后问题\n\n");
printf("输入皇后个数(1~20)n=:");
scanf("%d",&n);
while(n<1||n>20) //皇后个数输入不合法,提示重新输入
{
printf("输入的皇后个数不合法,请重新输入(1~20):\n");
scanf("%d",&n);
}
printf("%d个皇后的求解如下:\n",n);
place(1,n);
if(!flag)
printf("\t\t无解!\n");
printf("\n");
}