手撕八皇后问题,用回溯法哦(深度优先法)

问题描述:

在一个8*8的棋盘上,有8个皇后放置在棋盘上,两两不能对冲,即行 ,列,斜 只能放置一个皇后。

比如下图,第一行的皇后行 ,列,斜 只能放置一个皇后。

 

解答这种题,首先分析算法流程

这里有一个点特别注意,就是占位标志的判断,首先是列占位,这个直接标志就行了

但是斜线角怎么判断?

通常上对角,行号减去列号都是相等的,比如拿f[0][0] 来说,它的上对角是哪些呢?

行号0 -列号0 =0 ,它的对角行号减去列号都是0,我们可以用一个数组存储d1[0] = 0 ,表示占用,数组的下标是行号减去列号相减的结果。

注意:为了避免数组下标出现负号,所以相减结果统一加7(为什么是7,因为棋盘上,最小的负数是-7)

 

接下来下对角,行号加列号都是相等的,其他跟上面同理。但用另外的一个数组d2存储,方便判断

接下来要分析程序思想

代码:

      //八皇后问题
      var place = [] //存储皇后放置的列
      var flag = [1,1,1,1,1,1,1,1] //标志数组,表示第col列的皇后是否被占位。0表示占位,1表示没有
      var d1 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] //表示第col列的皇后的上对角线的标志位是否被占用
      var d2 = [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] //表示第col列的皇后的下对角线的标志位是否被占用
      function queen(n){
          for(var col =0 ;col <8;col++){
            if(flag[col] && d1[n-col+7] &&d2[n+col]){
              place[n] = col
              flag[col] = 0
              d1[n-col+7] = 0
              d2[n+col]  = 0
              if(n<7){
                queen(n+1)  //小于7,进行下一行
              }
              else{
                console.log("八皇后结果",place)
              }
              //找到一个解后,回溯上一个,看有没有其他解,所以上一个的占位标志要清除
              flag[col] = 1
              d1[n-col+7] = 1
              d2[n+col]  = 1
            }
          }
      }
      queen(0)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章