智能钥匙柜标准:n皇后问题

来源:百度文库 编辑:查人人中国名人网 时间:2024/04/29 18:13:01
以下为我写的n皇后问题求解程序,奇怪的是当N=8,结果为92,当N=9,结果居然为:332 ,与正确结果352差很多。当N=10 结果为304。也与正确结果不一样。

我测试了一下当N<=8时,能得出正确结果,当n>8时结果不正确。
求教各位,看看哪出了问题?
-----------------------------
/*
* n 皇后问题求解
* author:xy_xue
* data :2006/06/25
*/

#include "stdio.h"

#define MAX 8 //8 皇后
int a[MAX+1]; //location of queen
int b[2*MAX+1]; //has been done of slash:'/'
int c[2*MAX+1]; //has been done of backlash:'\'
int d[MAX+1]; //has been doen of columns: '|'

int total; //count of queen
output() //输出函数
{
int i,j;
int aa[MAX+1][MAX+1];
for (i=1;i<=MAX;i++)
for (j=1;j<=MAX;j++)
aa[i][j]=0; //输出数组初始化

for (i=1;i<=MAX;i++)
aa[i][a[i]]=1; //a[i]中存放的为皇后所在的列号,aa[1][a[1]]表示,第一行开始的第a[1]列有皇后

for (i=1;i<=MAX;i++)
{
printf("\n"); //回车
for (j=1;j<=MAX;j++)
{
if (aa[i][j]==1) //有皇后的位置为*,没有的位置为0
printf("*");
else
printf("0");
}
}
printf("\n");
}

isok(int i,int dep) //测试i,dep点是否可放
{
//printf("i=%d,dep=%d\n",i,dep);
//printf("%d,%d,%d,%d\n",b[i+dep],c[dep-i],a[dep],d[i]);
if ((b[i+dep]==1)&&(c[dep-i]==1)&&(a[dep]==0)&&(d[i]==1)) //'或'表达式,有一个为真则该位置不能放
{
return 1;
}
return 0;
}

tryit(int dep) //主要程序,实现皇后的搜索过程,i表示列,dep表示行
{
int i,j;

for (i=1;i<=MAX;i++) //对于某一行,从第一列到最后一列测试是否能放
{
if (isok(i,dep)) //如果能放,行、列、对角线数组放标志
{
a[dep]=i; //将当前列存到以当前行为下标的数组中。
b[i+dep]=0; //对角线'/'
c[dep-i]=0; //对角线'\'
d[i]=0; //列标志

if (dep==MAX) //是否到最后一行
{
total=total+1; //是,计数器加一,并输出。
// output();
}
else //没有到最后一行,则进入下一层,继续查找。
{
tryit(dep+1);
}
a[dep]=0; //以下四行语句在if (isok())的循环体内,递归之前。
b[i+dep]=1; //指的是当递归完成却没有找到正确的点时,执行递归之后的语句,即清除以前的尝试,回溯。
c[dep-i]=1;
d[i]=1;
}
}
}

main()
{
int i,j;

for(i=1;i<=MAX;i++)
{
a[i]=0; //皇后位置
d[i]=1; //列表志
}

for (i=2;i<=2*MAX;i++)
{
b[i]=1; //对角线标志
}

for (i=-(MAX-1); i<=(MAX-1);i++)
{
c[i]=1; //对角线标志
}
total=0;
tryit(1); //1表示从第一行开始查找
printf("\n------\nTotal:%d\n",total);
}