JavaScript题解 | #24点运算#
24点运算
https://www.nowcoder.com/practice/7e124483271e4c979a82eb2956544f9d
const rl = require("readline").createInterface({ input: process.stdin, output: process.stdout, }); rl.on("line", (line) => { judge24Point(line.split(" ")); }); function judge24Point(nums) { if (nums.includes("joker") || nums.includes("JOKER")) { console.log("ERROR"); return; } const numsMap = { J: 11, Q: 12, K: 13, A: 1, }; const temp = ["J", "Q", "K", "A"]; let arr = []; nums.forEach((v) => { if (temp.includes(v)) { arr.push(numsMap[v]); } else { arr.push(parseInt(v)); } }); let res = game24(arr); if (!res) { console.log("NONE"); } } // records 是用来装表达式的【4 + 2 * 13 + 1】 // used(visited) 是回溯里面必备的状态哨兵(标记已经访问了),用来回溯状态的 // 其余参数根据个人情况而定,用到啥写啥 function game24(nums, total = 0, records = [], used = []) { // 终止条件 if (records.length == 7) { // dfs找到结果了,输出对应的一条结果 if (total == 24) { let res = ""; for (let i = 0; i < 7; i++) { const temp = records[i]; if (["+", "-", "*", "/"].includes(temp)) { res += temp; } else { if (temp > 1 && temp < 11) { res += temp; } else { const numMap = { 1: "A", 11: "J", 12: "Q", 13: "K", }; res += numMap[temp]; } } } console.log(res); return true; } return false; } const numsLen = nums.length; for (let i = 0; i < numsLen; i++) { if (!used.includes(i)) { const a = nums[i]; if (records.length == 0) { used.push(i); if (game24(nums, a, [a], used)) return true; if (game24(nums, a, [a], used)) return true; if (game24(nums, a, [a], used)) return true; if (game24(nums, a, [a], used)) return true; used.pop(); } else { // 标准的回溯模板 // 1. 对标记做处理 used.push(i); // 2. 递归 if (game24(nums, total + a, records.concat(["+", a]), used)) return true; // 3. 回溯状态 used.pop(); used.push(i); if (game24(nums, total - a, records.concat(["-", a]), used)) return true; used.pop(); used.push(i); if (game24(nums, total * a, records.concat(["*", a]), used)) return true; used.pop(); used.push(i); // 这里还是按照题目要求的向下取整比较好,(total / a) >>> 0 if (game24(nums, total / a, records.concat(["/", a]), used)) return true; used.pop(); } } } }
难度:⭐⭐⭐⭐
差一星,在于给的测试用例不够正确,测例3如果使用(total / a)>>> 0自测是判error的,不过我试了最终判断是没问题的。
难点:
这道题和之前有道中等难度的24点很像,思路很像,但是这道题个人觉得更难一点。
1、 这道题计算顺序从左至右,不能包含括号
2、起始递归条件那里很不容易想到要dfs四次,一开始只写了一次,debug到最后发现一直都是4开头(用的测试用例3),后面的牌都遍历了,唯独第一张牌不变。这才想到该如何打乱第一张牌的顺序,那要不直接dfs四次得了。
3、难点3在于,一入递归深似海,再加上回溯条件搞不清楚。
目前做这种回溯的题还是有些迷迷糊糊,还是多做几道,仔细品,仔细品,仔细品。