公鸡5元一只,母鸡3元一只,小鸡一元3只,要求将100元刚好花光,并且刚好买100只鸡。 求:有哪几种买法,就是列出公鸡,母鸡,小鸡,各种数量的组合。

1. 穷举

假设全都买公鸡,那么公鸡的数量范围:0~20
全部买母鸡,母鸡的数量范围:0~33
小鸡的数量范围:100 - 公鸡 - 母鸡
双层遍历穷举碰结果

  1. function resolve() {
  2. let res = []
  3. for (let i = 0, len = 20; i < len; i++) {
  4. for (let j = 0, leng = 33; j < leng; j++) {
  5. let k = 100 - i - j;
  6. if (5 * i + 3 * j + k / 3 === 100 && k % 3 === 0) {
  7. let arr = [i, j, k]
  8. res.push(arr)
  9. }
  10. }
  11. }
  12. return res
  13. }
  14. console.log(resolve())

image.png


2. 解方程

(1) x + y + z = 100 ①
(2) 5x + 3y + z/3 = 100 ②
(3) x, y, z 均为非负整数
整理
可得:
y = 25 - 7x/4,且y为非负整数;
z = 75 + 3x/4,且z为整数(z显然大于0,因为x非负)。
由于y和z必须是整数,所以x必须是4的倍数。
用单层循环即可枚举出结果(代码如下)

function resolve1() {
      let res = []
      for (let x = 0; x < 100; x += 4) {
        if ((25 - 7 * x / 4) > 0 && (75 + 3 * x / 4) > 0) {
          if (x + (25 - 7 * x / 4) + (75 + 3 * x / 4) === 100) {
            let arr = [x, (25 - 7 * x / 4), (75 + 3 * x / 4)]
            res.push(arr)
          }
        }
      }
      return res
    }

表面上第二种方式是明显快于第一种方式的,但浏览器内部还有浏览器的编译器可能给做了某些神奇的优化,运行结果让人迷惑

image.png

image.png


测试代码

<body>
  <script>
    function resolve() {
      let res = []
      for (let i = 0, len = 20; i < len; i++) {
        for (let j = 0, leng = 33; j < leng; j++) {
          let k = 100 - i - j;
          if (5 * i + 3 * j + k / 3 === 100 && k % 3 === 0) {
            let arr = [i, j, k]
            res.push(arr)
          }
        }
      }
      return res
    }

    function resolve1() {
      let res = []
      for (let x = 0; x < 100; x += 4) {
        if ((25 - 7 * x / 4) > 0 && (75 + 3 * x / 4) > 0) {
          if (x + (25 - 7 * x / 4) + (75 + 3 * x / 4) === 100) {
            let arr = [x, (25 - 7 * x / 4), (75 + 3 * x / 4)]
            res.push(arr)
          }
        }
      }
      return res
    }

    function calcRunTime(func,method) {
      console.time('testForEach');
      var res = func();
      console.log('------',method,'--------')
      console.log(res)
      console.timeEnd('testForEach');
    }

    calcRunTime(resolve , 'resolve');
    calcRunTime(resolve1, 'resolve1');

  </script>
</body>