八皇后谜题:
八皇后是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。 高斯认为有76种方案。1854年在柏林的象棋杂志上不同的作者发表了40种不同的解,后来有人用图论的方法解出92种结果。计算机发明后,有多种计算机语言可以解决此问题。
八皇后问题是把八个象棋皇后放在一个8×8棋盘上的问题,这样就不会有两个皇后互相威胁。因此,一个解决方案要求没有两个皇后共享同一行、列或对角线。八皇后难题是一个更一般的N皇后问题的例子,将n个非攻击皇后放置在n×n棋盘上,对于n个n=2和n=3的例外,所有自然数n都存在解。
求解方案:
这个问题在计算上是相当昂贵的,因为在8×8板上有八个皇后的4426165368个(即,64个C8)可能布置,但是只有92个解决方案。有可能使用快捷方式,减少计算要求或经验法则,避免蛮力计算技术。例如,通过应用将每个皇后约束为单个列(或行)的简单规则,尽管仍被认为是蛮力,可以将可能性的数量减少到16777216(即,88)可能的组合。生成排列进一步将可能性降低到40320(即8!)。,然后检查对角线攻击。
程序求解:
void main()
{
int a[256]={0};
int i=1,j,n,t=1; //i表示当前正在搜索第i行的皇后位置
printf("请输入几皇后?n=");
scanf("%d",&n);
while(i>0)
{
for(a[i]++;a[i]<=n;a[i]++)
{
if(Check(a,i)) //如果第i行的皇后与之前的皇后位置上没有冲突,则break跳出循环
break;
}
if(a[i]<=n) //如果a[i]<=n,即上面的for循环是由“break;”跳出来的,即第i行皇后的位置符合条件
{
if(i==n) //找到一组解,输出
{
printf("第%d种解法:\n",t++);
for(j=1;j<=n;j++)
printf("第%d个皇后:%d\n",j,a[j]);
printf("\n\n");
}
else
{
i++;
a[i]=0;
}
}
else
i--;
}
}