棋盘n皇后问题-递归

题目:在n*n的棋盘上,放n个皇后,互不攻击(不可在同行/列/对角线)

分析:将棋盘抽象成一个一维数组[0,1,2......,n*n-1],x=~~(i/n)取整,y=i%n;
         decisions是放n个皇后的一维坐标

代码:queen(n)可获得最后结果。

function queen(n, decisions=[], decisionSet=new Set()) {
  if (decisions.length === n) {
    /***过滤重复内容*********/
    decisions.sort((a,b) => a-b);
    const hash = decisions.join('-');
    if (decisionSet.has(hash)) return [];
    decisionSet.add(hash);
    /**********************/
    return [decisions];
  }
  let r = [];
  for(let i = 0;i < n*n; i++) {
    if(decisions.indexOf(i) === -1) {
      // 保证遍历的内容不存在攻击
      if (decisions.every(item => compatible(item, i, n))) {
        r = r.concat(queen(n, decisions.concat(i), decisionSet))              
      } 
    }
  }
  return r;
}
//判断decisions是否符合要求,数组内两两比较
function is_goal(n, decisions) {
  for(let i = 0; i < n; i++) {
    for(let j = i+1; j < n; j++) {
      if(i===j) continue;
      const p = decisions[i];
      const q = decisions[j];
      if(!compatible(p,q,n)) {
        return false
      }
    }
  }
  return true;
}
function compatible(p,q,n) {// 判断位置p,q是否存在互相攻击
  const [x1, y1] = [~~(p/n), p % n];
  const [x2, y2] = [~~(q/n), q % n];
  return x1!==x2 && y1!==y2 && Math.abs(x1-x2) !== Math.abs(y1-y2)
}

 

posted @ 2019-11-19 16:31  Lyra李  阅读(355)  评论(0编辑  收藏  举报