zoukankan      html  css  js  c++  java
  • 八皇后问题 回溯法

    问题描述:

    八皇后问题是十九世纪著名数学家高斯于1850年提出的。问题是:在8*8的棋盘上摆放8个皇后,使其不能互相攻击,即任意的两个皇后不能处在同意行,同一列,或同意斜线上。可以把八皇后问题拓展为n皇后问题,即在n*n的棋盘上摆放n个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上。

    问题分析  

    显然,每一行可以而且必须放一个皇后,所以n皇后问题的解可以用一个n元向量X=(x1,x2,.....xn)表示,其中,1 i n且1 xi n,即第n个皇后放在第i行第xi列上。

    由于两个皇后不能放在同一列上,所以,解向量X必须满足的约束条件为:

    xi xj;

    若两个皇后的摆放位置分别是(i,xi)和(j,xj),在棋盘上斜率为-1的斜线上,满足条件i-j=xi-xj;在棋盘上斜率为1的斜线上,满足条件i+j=xi+xj;

    综合两种情况,由于两个皇后不能位于同一斜线上,所以,

    解向量X必须满足的约束条件为:

    |i-xi| |j-xj|

    代码如下:哈哈 

     
    #include<stdio.h>
    #include<math.h>
    int x[100];
    bool place(int k)//考察皇后k放置在x[k]列是否发生冲突
    {
        int i;
        for(i=1;i<k;i++)
            if(x[k]==x[i]||abs(k-i)==abs(x[k]-x[i]))
                return false;
            return true;
    }

    void queue(int n)
    {
        int i,k;
        for(i=1;i<=n;i++)
            x[i]=0;
        k=1;
        while(k>=1)
        {
            x[k]=x[k]+1;   //在下一列放置第k个皇后
            while(x[k]<=n&&!place(k))
                x[k]=x[k]+1;//搜索下一列
            if(x[k]<=n&&k==n)//得到一个输出
            {
                for(i=1;i<=n;i++)
                    printf("%d ",x[i]);
                printf("\n");
            //return;//若return则只求出其中一种解,若不return则可以继续回溯,求出全部的可能的解
            }
            else if(x[k]<=n&&k<n)
                k=k+1;//放置下一个皇后
            else
            {
                x[k]=0;//重置x[k],回溯
                k=k-1;
            }
        }
    }

    void main()
    {
       int n;
       printf("输入皇后个数n:\n");
       scanf("%d",&n);
       queue(n);
    }

      

  • 相关阅读:
    菜鸟看懂算法以后之一:头痛的64次左移
    C语言通过指针数组和二维数组读取文件
    C++中构造函数调用构造函数
    bnuoj53075 外挂使用拒绝
    [CodeForces]String Reconstruction
    BNU-2017.7.4排位赛2总结
    BNU-2017.7.5排位赛3总结
    BNU-2017.7.3排位赛1总结
    微软大楼设计方案(困难)
    最长公共子序列针对小字符集的算法
  • 原文地址:https://www.cnblogs.com/qinyg/p/2512353.html
Copyright © 2011-2022 走看看