算法问题:8升满壶5升3升空壶倒出4升水,js遍历实现

题目

给一个装满水的 8 升满壶和两个分别是 5 升、3 升的空壶,想个办法,使得其中一个水壶恰好装 4 升水,每一步的操作只能是倒空或倒满。

这种问题,给你一张纸,给你20分钟,枚举一下,应该很容易就可以得出答案。但是,怎么用代码实现呢?似乎有点费脑

先回答几个问题:

1、怎么遍历杯子

2、每次操作会产生多少种可能性

3、怎么防止操作后出现重复的组合

搞定这几个问题,应该就可以写代码了,同时可以拓展一下题目,

给一个装满水的 n升满壶和两个分别是 m升、o升的空壶,想个办法,使得其中一个水壶恰好装 a 升水,每一步的操作只能是倒空或倒满。

下面可以算出一共有多少种方法实现这个需求

 var arr = [
      {
        volume: 8,
        limit: 8,
      },
      {
        volume: 0,
        limit: 5,
      },
      {
        volume: 0,
        limit: 3,
      },
    ];
    var historyArr = [arr];
    var count = 1
    var stepsArr = [
      {
        step: 0,
        val: arr.map((obj) => obj.volume).join(',')
      }
    ]
    function operate(arr, count) {
      var resultArr = [];
      for (var i = 0; i < arr.length; i++) {
        // 每次操作一个有水的杯子
        for (var k = 0; k < arr.length; k++) {
          var choiceArr = JSON.parse(JSON.stringify(arr));
          if (i !== k && arr[i].volume && arr[k].volume < arr[k].limit) {
            var distance = (arr[k].limit - arr[k].volume);
            // 判断操作杯子的水多,还是被倒水的杯子剩余容量多
            choiceArr[i].volume -= (distance >= arr[i].volume ? arr[i].volume : distance);
            choiceArr[k].volume += (distance >= arr[i].volume ? arr[i].volume : distance);
            // 如果还没记录该次组合,则放入记录
            if (!JSON.stringify(historyArr).includes(JSON.stringify(choiceArr))) {
              historyArr.push(choiceArr);
              resultArr.push(choiceArr);

              //记录每次操作产生组合的数量
              if (!stepsArr[count]) {
                stepsArr[count] = [{
                  step: count,
                  val: choiceArr.map((obj) => obj.volume).join(',')
                }]
              } else {
                stepsArr[count].push({
                  step: count,
                  val: choiceArr.map((obj) => obj.volume).join(',')
                })
              }
            }
            if (choiceArr[i].volume == 4 || choiceArr[k].volume == 4) {
              // 终止递归
              //  console.log(historyArr);
              console.log(JSON.stringify(stepsArr));
              return;
            }
          }
        }
      }
      count++;
      for (var n = 0; n < resultArr.length; n++) {
        operate(resultArr[n], count)
      }
    }
    operate(arr, count)

 

posted @ 2020-06-09 18:24  kzc275  阅读(616)  评论(0编辑  收藏  举报