用马走完棋盘

起因是最近在玩《雷顿教授与恶魔之箱》,遇到一个问题,用马走完国际象棋的棋盘(走日字,一个格子只能走一次),试了试,挺难的,尤其是棋盘大了以后,所以就想到了八皇后,感觉差不多,然后就想,嗯,不如写个程序来试试,结果发现已经不记得八皇后怎么写了,所以先看了下八皇后怎么写。

贴一下https://blog.csdn.net/gohike/article/details/53359691这篇里的实现

var n = 8;
var arr = [];
function queen(index) {
      if (index === n) {
        console.log(arr);
      } else {
        for (var i = 0; i < n; ++i) {
          arr[index] = i;
          var flag = true; 
          for (var j = 0; j < index; ++j) {
            if (arr[index] === arr[j] || arr[index] - arr[j] === index - j || arr[index] - arr[j] === j - index) {
              flag = false;
              break;
            };
          };
          if (flag) {
            queen(index + 1);
          }
        }
      }
    }

queen(0);

我看了看,觉得稍微有一点点不太容易理解,所以改了改,把上面用arr的索引来作为行的方式改成了(x,y),回退的步骤也更明显了一点,结果发现我写的这种执行一下21ms,而上面这种2ms(捂脸)

var n = 8;
var arr = [];
function queen(index) {
      if (index === n) {
        console.log(arr.slice(0)); // 直接console.log(arr)的话可以发现无法展开看arr的值
      } else {
        for (var i = 0; i < n; ++i) {
          arr.push({x:index,y:i}); // x表示行,y表示列
          var flag = true; 
          for (var j = 0; j < index; ++j) {
            if ((Math.abs(arr[index].x - arr[j].x) === Math.abs(arr[index].y - arr[j].y)) 
            || (arr[index].y === arr[j].y)) {
              flag = false;
              arr.pop(); // 回退一步
              break;
            };
          };
          if (flag) {
            // 进入下一行
            queen(index + 1);
          }
        }
      }
      // 两个循环都执行完了发现不行,那么回退一步,这步也会导致arr把所有可能穷尽一遍
      arr.pop();
    };
    queen(0);

下面是马走棋盘的代码,6行5列执行结果有4542种走法,执行一下大概要花半分钟,惊了

    var n = 6, m = 5;// n表示行,m表示列
    var arr = [{x:1,y:1}];
    var aaa = 0; // 计数用
function inRange(pos){
      if(pos.x > n || pos.y > m || pos.x < 1 || pos.y < 1){ // 判断有没有跳出棋盘外
        return false;
      }
      for(let i=0, len=arr.length; i<len; i++){ // 判断有没有走过
        if(arr[i].x === pos.x && arr[i].y === pos.y){
          return false;
        }
      }
      return true;
    }
    function getPos(x,y,index){
      switch(index){
        case 1:
          return {x:x+1,y:y+2}
        break;
        case 2:
          return {x:x+1,y:y-2}
        break;
        case 3:
          return {x:x+2,y:y+1}
        break;
        case 4:
          return {x:x+2,y:y-1}
        break;
        case 5:
          return {x:x-1,y:y+2}
        break;
        case 6:
          return {x:x-1,y:y-2}
        break;
        case 7:
          return {x:x-2,y:y+1}
        break;
        case 8:
          return {x:x-2,y:y-1}
        break;
      }
    }
    function horse(index){
      if(index === n*m){
        aaa++; 
      }else{
        for(let i=1; i<9; i++){
          let temp = getPos(arr[index-1].x,arr[index-1].y,i);
          if(inRange(temp)){
            arr.push(temp);
            horse(index+1);
          }
        }
      }
      // 8个位置走完发现没有可跳的
      arr.pop();
    }

    horse(1);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值