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在于,一入递归深似海,再加上回溯条件搞不清楚。
目前做这种回溯的题还是有些迷迷糊糊,还是多做几道,仔细品,仔细品,仔细品。

