这个是我以前的笔记:
八皇后问题:
初步设计:8层嵌套循环
n为某列,h为所在行数
我假设某点为-1则,该点因为前面的皇后而被约束,
为0,为初始值
为1,表示放有皇后 /*当然这样有很多的多余,例如1,根本不需要设置,形同虚设*/
我的约束是:当a[h][n]=1,则设置a[h][k]=-1;a[h+k][n+k]=-1;a[h-k][n+k]=-1 ,k为0到7 /*会出现很多的问题,可毕竟是初步嘛 :> */
for 对于第一列的每行分析
if 该点适合(适合条件为:该点为0)
BEGIN 保存该点(queuen[1]=h)
. 设置约束
. for 对于第二列的每行进行分析
. if 该点适合
. BEGIN 保存该点
. . 设置约束
. . for ...
. . IF ..
. . BEGIN...
. . .
. . .
. .
. . END
. .
. .
. .
. .
. .
. 清除该次保存点
. 清除该次设置的约束
. END /*将进行对该列的下一行分析*/
.
.清除第一列该次保存点
清除该次设置的约束
END /*将分析第一列的下一行*/
其中有一个特殊的即最后一层的循环 /*特殊是因为,它是最后一层要处理输出,
代码:
for(i_7=0;i_7<8:i_7++)
if(a[i_7][7]==0)
{
queuen[7]=i_7;
循环输出;
}
再次分析:/*分析来在与书上提供的代码的对比来*/
从上面的算法看,它很象递归形式
为什么怎样说了:
1,每次做的事,都是相同的事情
2,很有层次感
3,虽然最后一次的嵌套,有所不一样,但正是递归所需要的/*递归必须向某一个条件靠拢,这样才不会是个死循环递归*/
算法:
queuen(n:分析的第n列)
{for 对第n列的每一行分析
{if 合适
{
queuen[n]=该点所在的行数
设置约束;
if {
这时候分析的是第8行
输出结果
}
ELSE
回调 queuen(++n) /*分析下一列*/
/*到这里是因为,对这列的这行所有的情况已经分析完了*/
清除本次设置的约束
}
最后的程序代码: /*来在其他的书籍*/
#include "stdio.h"
int col[8],left[15],right[15];
int queen[8];
int n=0;
int sum=0;
void generate()
{
int h,in;
for(h=0;h<=7;h++)
{ if(col[h]&&left[n+h]&&right[n-h+7])
{ queen[n]=h;
col[h]=0;
left[h+n]=0;
right[n-h+7]=0;
n+=1;
if(n==8)
{
sum++;
printf("%d:",sum);
for(in=0;in<=7;in++)
printf("\t\%d",queen[in]);
printf("\n");
}
else generate();
n--;
left[n+h]=1;
right[n-h+7]=1;
col[h]=1;
}
}
}
void main()
{
int c,s;
for(c=0;c<=7;++c)
col[c]=1;
for(s=0;s<=14;++s)
{ left[s]=1;
right[s]=1;
}
printf("行数:\t0\t1\t2\t3\t4\t5\t6\t7\n");
generate();
printf("八皇后的总排法数为:%d",sum);
}
上面的约束有点难: :)资料也没,只好硬着去想拉!
不得不说上面的约束条件太巧了,分三个约束:
1,所在行的约束col[8],即不能在同一行有两个皇后的约束
2,某两条对角线上的约束,left[17],right[17]
3,所在列的约束,这就简单拉
难点是第二中约束:
它将两中对角线的约束,分别映射到两个数组上,但却使得它适合对每一列的约束,它是这样做到的了?
对于不同的列的,真正起约束的是那些下标为:n到n+7到元素
1,对left[n+h]分析:
例如对于第5列,第6行所产生的约束是left[5+6],而对第6行来说,left[11]约束的是这列的第5行
而对第7行来说,left[11]约束的是这列的第4行
画一下图就晓得,这写点都在一个对角线上
2,对right[7-h+n]分析:
例如对于上面的点,产生的约束是right[7-6+5],对于第6行来说,right[6]约束的是这列的第7行 /*6=7-h+6 ->h=7*/
对于第4行来说,right[6]约束的是这列的第5行 /*6=7-h+4 ->h=5*/
画一下图又发现,这些点都在另外的一条对角线上
:)是不是很巧啊,可是怎么发现这爽的规律的了 /*这就要看人的思维本事了,我没想到这来,可能是我还没想到优化,能不能想到这个规律,难说 - -! */
想出来与看不看的懂就是两回事了