文档章节

8皇后问题

沉默的懒猫
 沉默的懒猫
发布于 2017/04/07 14:17
字数 1379
阅读 9
收藏 0

 首先,可归纳问题的条件为,8皇后之间需满足:

             1.不在同一行上

             2.不在同一列上

             3.不在同一斜线上

             4.不在同一反斜线上

 

     这为我们提供一种遍历的思路,我们可以逐行或者逐列来进行可行摆放方案的遍历,每一行(或列)遍历出一个符合条件的位置,接着就到下一行或列遍历下一个棋子的合适位置,这种遍历思路可以保证我们遍历过程中有一个条件是绝对符合的——就是下一个棋子的摆放位置与前面的棋子不在同一行(或列)。接下来,我们只要判断当前位置是否还符合其他条件,如果符合,就遍历下一行(或列)所有位置,看看是否继续有符合条件的位置,以此类推,如果某一个行(或列)的所有位置都不合适,就返回上一行(或列)继续该行(或列)的其他位置遍历,当我们顺利遍历到最后一行(或列),且有符合条件的位置时,就是一个可行的8皇后摆放方案,累加一次八皇后可行方案的个数,然后继续遍历该行其他位置是否有合适的,如果没有,则返回上一行,遍历该行其他位置,依此下去。这样一个过程下来,我们就可以得出所有符合条件的8皇后摆放方案了。这是一个深度优先遍历的过程,同时也是经典的递归思路。

     

      接下来,我们以逐列遍历,具体到代码,进一步说明。首先,从第一列开始找第一颗棋子的合适位置,我们知道,此时第一列的任何一个位置都是合适的,当棋子找到第一个合适的位置后,就开始到下一列考虑下一个合适的位置,此时,第二列的第一行及第二行显然就不能放第二颗棋子了,因为其与第一个棋子一个同在一行,一个同在一条斜线上。第二列第三行成为第二列第一个合适的位置,以此类推,第三列的第5行又会是一个合适位置,这个过程中,我们注意到,每一列的合适位置都是受到前面几列的位置所影响,归纳如下:

       

      假设前面1列的棋子放在第3行,那当前列不能放的位置就一定是3行,2行,4行。因为如果放在这三行上就分别跟前一列的棋子同在一行、同在斜线、同在反斜线上,不符合我们的要求。现在我们用cols数组来表示8个列棋子所放的行数,数组下标从0开始,其中数组下标表示列数,数组的元素值表示该列棋子所在行数,当前列为N(N>=0,N<8),即cols[N-1]=3,则有:

                          

                      cols[N] != cols[N-1](=3,表示不在同一行)

                     

                      cols[N] != cols[N-1]-1(=3-1=2,表示不在同一斜线上)

                     

                      cols[N]!=cols[N-1]+1(=3+1,表示不在同一反斜线上)

 

      这里我们注意到,如果N-2列存在的话,那么我们还要考虑当前列N不与N-2列的棋子同行,同斜线,同反斜线。把当前列N的前面的某一列设为m,则m的所有取值为{m>=0,m<N}的集合,故又可在上面式子的基础,归纳为如下:

                   

                    cols[N] != cols[m](与第m列的棋子不在同一行)

                   

                    cols[N] != cols­­[m] -(N-m)(>=0 ,与第m列的棋子不在同一斜线上)

                   

                    cols[N] != cols­­[m] + (N-m)  (<=8-1,与第m列的棋子不在同一反斜线上)          

 

           具体到代码,很显然,取m的所有值只需要一句循环,同时我们为每一列定义一个长度为8的布尔数组row[],下标同样是从0开始,我们规定当row[i]=true时,表示该列第i行不能放棋子。这样我们就能写成下列程序段了:

public class Queen8 {  
    public static int num = 0; //累计方案总数  
    public static final int MAXQUEEN = 8;//皇后个数,同时也是棋盘行列总数  
    public static int[] cols = new int[MAXQUEEN]; //定义cols数组,表示8列棋子摆放情况  
    public Queen8() {  
       //核心函数  
      getArrangement(0);  
      System.out.println(MAXQUEEN+"皇后问题有"+num+"种摆放方法。");  
    }  
      
    public void  getArrangement(int n){  
     //遍历该列所有不合法的行,并用rows数组记录,不合法即rows[i]=true  
     boolean[] rows = new boolean[MAXQUEEN];  
     for(int i=0;i<n;i++){  
       rows[cols[i]]=true;  
        int d = n-i;  
        if(cols[i]-d >= 0)rows[cols[i]-d]=true;  
        if(cols[i]+d <= MAXQUEEN-1)rows[cols[i]+d]=true;   
        
     }  
     for(int i=0;i<MAXQUEEN;i++){  
       //判断该行是否合法    
       if(rows[i])continue;  
       //设置当前列合法棋子所在行数  
      cols[n] = i;  
       //当前列不为最后一列时  
       if(n<MAXQUEEN-1){  
        getArrangement(n+1);  
      }else{  
  
       //累计方案个数  
        num++;  
        //打印棋盘信息  
        printChessBoard();  
      }   
       
        
     }  
       
    }  
    public void printChessBoard(){  
         
      System.out.println("第"+num+"种走法 ");  
        
      for(int i=0;i<MAXQUEEN;i++){  
       for(int j=0;j<MAXQUEEN;j++){  
          if(i==cols[j]){  
           System.out.print("0 ");  
          }else  
            System.out.print("+ ");  
        }  
        System.out.println("");  
      }  
       
   }  
    public static void main(String args[]){  
     Queen8 queen = new Queen8();  
   }  
     
} 

 

本文转载自:http://blog.csdn.net/zhong317/article/details/4586131

共有 人打赏支持
沉默的懒猫
粉丝 7
博文 96
码字总数 36024
作品 0
海淀
程序员
回溯算法思想与八皇后问题解的个数

八皇后问题: 在88的国际象棋棋盘上,皇后是威力较大的棋子,它可以攻击到与自己同行、同列以及同一斜线上的棋子,如下图,所有橙色格子上的棋子,都可能会被皇后攻击: 而八皇后问题就是在8...

silenceyawen
03/04
24
0
小朋友学经典算法(14):回溯法和八皇后问题

一、回溯法 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不...

海天一树X
10/09
0
0
八皇后问题的递归解法(最易理解的版本)

八皇后问题是一个古来而著名的问题,该问题是19世纪著名的数学家高斯同学提出来的。在8*8的国际象棋上摆放八个皇后,使其不能互相的攻击,也就是说,任意的两个皇后不能放在同一行或则是同一...

simpower
07/10
0
0
迭代回溯 ---8皇后

八皇后问题 就是在8*8格子上放8个皇后 皇后是可以横行竖行斜行行走 他们之间不能存在可以被吃的关系 算法 迭代回溯法 思路是这样 红色框代表put 函数里的if没有通过 就不再有进一步迭代(子树...

Ink_cherry
2017/05/16
0
0
JavaScript之八皇后问题(递归)

  八皇后问题,是一个古老而著名的问题,该问题最早由国际西洋棋棋手马克斯·贝瑟尔(Max Bezzel)于1848年提出。八皇后问题的具体描述为:在8×8的国际象棋上摆放8个皇后,使其不能互相攻击...

jclian91
01/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

申请Let's Encrypt永久免费SSL证书

环境安装 1、安装git yum install git-core 2、安装python 系统自带 不用安装 只要版本大于2.7即可。 获取Let's Encrypt免费SSL证书 先停止nginx 在阿里云安全组里加入 443端口的入规则 git ...

HGMrWang
28分钟前
1
0
如何使用playframework进行更好的开发

1: 自定义基类Controller 相信刚开始使用Play的人写的Controller 都继承于 play.mvc.Controller , 但这并不是一个很好的选择,自建基类Controller可以扩展更多的功能。 1.1 验证功能。 后台...

tuerqidi
33分钟前
4
0
解决ubuntu下root用户 不能ftp登陆的问题

解决ubuntu下root用户 不能ftp登陆的问题 一般情况下,由于种种原因ftp是不让root用户远程登陆,但只要你修改以个文件就可以登陆了. 注释掉 /etc/ftpusers 中的root即可 (最后重启vsftpd serv...

15834278076
45分钟前
0
0
《JavaScript高级程序设计(第3版)》阅读笔记

第6章 面向对象的程序设计 6.2 创建对象 6.2.1 工厂模式 JavaScript创建对象(一)—— 工厂模式 6.2.2 构造函数模式 JavaScript创建对象(二)——构造函数模式 6.2.3 原型模式 JavaScript...

Bob2100
49分钟前
1
0
Windows小技巧 – Win+R提高Windows使用效率

追求效率的朋友都需要一款顺手的快速启动工具,Win 平台上有键盘流的RunZ、Listary、ALTRun、Launchy、Wox 和图标流的 Fences、Rolan、 WinLaunch 等,而 Mac 上也有 Alfred、Spotlight。 而...

QQZZFT
52分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部