回溯算法求解----八皇后puzzle

八皇后谜题:

八皇后是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于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--;
    }  
}  
    原文作者:八皇后问题
    原文地址: https://blog.csdn.net/xy294636185/article/details/80025560
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞