雨中黄叶树,灯下白头人
最近刷题一直没停,但是因为做的题比较重复而且不太难,就没有写题解。
今天做了一道挺有意思的题目,然后正好周六在家休息,就写一下。
思路基本就是模拟24点的求法,我一开始认为数字的相对位置不能变,所以是用栈去模拟的。。。然后又看了下给的示例,才发现数字的位置可以任意调整的,也就是运算发生在任意两个数之间。
既然是任意两个数,那直接暴力的话应该问题不大(其实我也想不到非暴力的方法)。
思路就是每次从列表里取出任意两个数分别进行四则运算,然后把计算的结果再次放入到列表中。直到列表中只剩下一个数,然后看这个数是否等于24即可。
要注意的地方:
- 因为除法不能按照整数除法来算,所以所有数都要转化成浮点数
- 浮点数之间的比较不能直接用
==
- 注意不能除 0 。。。
代码:
class Solution {
private:
static bool check(double v, double target) {
return abs(v - target) < 1e-6;
}
static double add(double a, double b) {
return a + b;
}
static double mul(double a, double b) {
return a * b;
}
static double div(double a, double b) {
return a / b;
}
static double abst(double a, double b) {
return a - b;
}
static vector<std::function<double(double, double)>> cals;
bool dfs(vector<double> l) {
if (l.size() > 1) {
for (int i = 0; i < l.size(); i++) {
for (int j = 0; j < l.size(); j++) {
if (i == j) continue;
vector<double> ll;
for (int k = 0; k < l.size(); k++) {
if (k != i && k != j) ll.emplace_back(l[k]);
}
for (int k = 0; k < 4; k++) {
if (k == 2 && check(l[j], 0.0)) continue;
double val = cals[k](l[i], l[j]);
ll.emplace_back(val);
if (dfs(ll))
return true;
ll.pop_back();
}
}
}
return false;
}
return check(l.back(), 24.0);
}
public:
bool judgePoint24(vector<int>& nums) {
vector<double> l;
cals.emplace_back(add);
cals.emplace_back(mul);
cals.emplace_back(div);
cals.emplace_back(abst);
for (auto it : nums)
l.emplace_back(static_cast<double>(it));
return dfs(l);
}
};
vector<std::function<double(double, double)>> Solution::cals;