题解 | #24点游戏算法#

24点游戏算法

https://www.nowcoder.com/practice/fbc417f314f745b1978fc751a54ac8cb

// 其实就是4个数字有4!=24种排列组合,两种计算逻辑(16+144=160种计算方式),最终极限情况下需要24*160=3840种结果都计算出来,才能知道是否能得到24点。
const rl = require("readline").createInterface({ input: process.stdin });
var iter = rl[Symbol.asyncIterator]();
const readline = async () => (await iter.next()).value;

void (async function () {
  // Write your code here
  // 组装四种计算结果
  function fn(x, y) {
    return [x + y, x - y, x / y, x * y];
  }
  // 组装六种计算结果
  function fn2(x, y) {
    return [x + y, x - y, x / y, x * y, y - x, y / x];
  }
  while ((line = await readline())) {
    // line = "2 9 9 5";
    let [a, b, c, d] = line.split(" ").map((item) => parseInt(item));
    let result = [];
	// 4个数字 24种顺序组合
    let arry = [
      [a, b, c, d],
      [a, b, d, c],
      [a, c, d, b],
      [a, c, b, d],
      [a, d, c, b],
      [a, d, b, c],
      [b, a, c, d],
      [b, a, d, c],
      [b, c, d, a],
      [b, c, a, d],
      [b, d, c, a],
      [b, d, a, c],
      [c, a, b, d],
      [c, a, d, b],
      [c, b, d, a],
      [c, b, a, d],
      [c, d, b, a],
      [c, d, a, b],
      [d, a, b, c],
      [d, a, c, b],
      [d, b, c, a],
      [d, b, a, c],
      [d, c, b, a],
      [d, c, a, b],
    ];
    let flag = false;
	// 遍历,计算每一种数字组合
    arry.forEach((item) => {
      if (flag) {
        return false;
      }
      let [x1, x2, x3, x4] = item;
      // 计算第一种情况 
	  // 逻辑为:x1,x2,计算,x3,x4,计算,计算
	  // 解释:先拿x1和x2 得到res1(四种计算结果),再用x3,x4 得到res2(四种计算结果 )
	  // x-y和y-x 两种计算方式,在遍历过程中,会出现x,y 和y,x两种顺序,无需重复计算多次
	  // 得到res1 和res2 两个结果集,交叉得到16个结果,如果包含24 ,设置状态,及时跳出后续的循环
      let res1 = fn(x1, x2);
      let res2 = fn(x3, x4);
      res1.forEach((val1) => {
        if (flag) {
          return false;
        }
        res2.forEach((val2) => {
          if (flag) {
            return false;
          }
          let tempArry = fn(val1, val2);
          if (tempArry.includes(24)) {
            // console.log(true, x1, x2, x3, x4, val1, val2, 'case1'); // 调试
            console.log(true);
            flag = true; // 如果包含24,修改状态
          }
        });
      });
      if (flag) {
        return false;
      }
	  // 计算第2种情况 这时候需要考虑一个问题(x1+x2)/x3 和 x3/(x1+x2) ,x1*x2-x3 和 x3-x1*x2 是不同的计算方式,不会因为数据顺序变化,而重复,需要额外交换计算一次。
	  // 逻辑为:x1,x2,计算,x3,计算,x4,计算
 	  // 解释:
	  // step1:先拿x1和x2 得到res3(x1和x2会因为数据交换产生被减被除,所以只考虑加减乘除,4个结果),
	  // step2:res3和x3交叉得到res4 (4*6 24个结果,此时需要考虑被除 被减)
	  // step3:res4和x4交叉得到res5 (24*6 144个结果,此时需要考虑被除 被减),如果结果里包含24 ,设置状态,及时跳出后续的循环
      let res3 = fn(x1, x2);
      res3.forEach((val3) => {
        if (flag) {
          return false;
        }
        let res4 = fn2(val3, x3);
        res4.forEach((val4) => {
          if (flag) {
            return false;
          }
          let res5 = fn2(val4, x4);
          if (res5.includes(24)) {
            // console.log(true, x1, x2, x3, x4, val3, val4, 'case2'); // 调试
            console.log(true); // 如果包含24,修改状态
            flag = true;
          }
        });
      });
      if (flag) {
        return false;
      }
    });
    if (!flag) {
      console.log(false);
    }
  }
})();

全部评论

相关推荐

zzzilik:没事的,才刚刚开始,后面会捞的,这个三天没人发起面试自动结束,但是面试官还是能看到简历,四月份主战场会慢慢捞
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务