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

    八皇后问题是一个古老而著名的问题,是回溯算法的典型例题。该问题是十九世纪著名的数学家高斯1850年提出:在国际象棋棋盘8行8列上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,求有多少种摆放方法。

    #include <stdio.h>
    int iCount = 0;//已经放了多少的皇后
    int Queens[8];//皇后放的行数,每个皇后必然占据一列,Queens[5]为第5列皇后放置的行数。
    
    int IsValid(int n)//断第n个皇后是否与前面皇后行成攻击
    {
       int i;
       for (i = 0; i < n; i++)//第n个皇后与前面n-1个皇后比较 
       {
           if (Queens[i] == Queens[n])//两个皇后在同一行上,返回0。
             return 0;
           if (abs(Queens[i] - Queens[n]) == (i - n))//两个皇后在同一对角线上,返回0。
             return 0;
       }
       return 1;//没有冲突,返回1。
    }
    
    //依次从第0列第一列第二列确定每列皇后放置的行数。
    void Queen(int n)//求第n列中哪行放置皇后
    {
       int i;
       if (n == 8)//第8列排完则8个皇后已放置完成
       {
          return;
       }
       for (i = 1; i <= 8; i++)//对第n列的每行上循环,从第一行开始。每列都是从0行开始检测
       { 
          Queens[n] = i;//假设第n列上放置在第i行 
          if (IsValid(n))//没有冲突,就开始下一列的试探
             Queen(n + 1); //递归调用进行下一步 
       }
    }
    int main()
    { 
       printf("八皇后排列方案:
    "); 
       Queen(0);//从第0列开始递归试探 
       getch();
       return 0;
    }

    我们将棋盘看作是一个8*8的数组,这样可以使用一种蛮干的思路去解决这个问题,这样我们就是在8*8=64个格子中取出8个的组合,C(64,80) = 4426165368,显然这个数非常大,在蛮干的基础上我们可以增加回溯,从第0列开始,我们逐列进行,从第0行到第7行找到一个不受任何已经现有皇后攻击的位置,而第五列,我们会发现找不到皇后的安全位置了,前面四列的摆放如下:

    image

    第五列的时候,摆放任何行都会上图所示已经存在的皇后的攻击,这时候我们认为我们撞了南墙了,是回头的时候了,我们后退一列,将原来摆放在第四列的皇后(3,4)拿走,从(3,4)这个位置开始,我们再第四列中寻找下一个安全位置为(7,4),再继续到第五列,发现第五列仍然没有安全位置,回溯到第四列,此时第四列也是一个死胡同了,我们再回溯到第三列,这样前进几步,回退一步,最终直到在第8列上找到一个安全位置(成功)或者第一列已经是死胡同,但是第8列仍然没有找到安全位置为止。

  • 相关阅读:
    云钉一体应用创新:音视频如何带来灵活高效的协同体验
    正则表达式,去除非数字。js动态计算
    使用DbContext实体类访问数据库
    C#字符串去除特殊字符
    实体类赋值给控件,控件赋值给实体类
    List去除重复项。
    分页查询的sql语句
    js页面处理常见问题
    .net Table 导出Excel
    上传文件。普通和ftp
  • 原文地址:https://www.cnblogs.com/yaowen/p/4499873.html
Copyright © 2011-2022 走看看