解题思路
1、整数转换为浮点数求解,因为除法可能会出现小数
2、浮点数和24比较,确定一个精度误差
3、枚举所有的可能,如果达到24进行剪枝
核心
- 在4个数中任选两个数进行四则运算,假设为
a op b = x
,此时在数组中删除a
和b
,把x
加入数组中,在剩下的三个数里任选两个进行四则运算。 - 当数组中只剩下一个数时,说明运算完成,与24比较即可。
代码
class Solution {
public:
const double eps = 1e-8;
double f(double a,double b,int op){
switch(op){
case 0:return a + b;
case 1:return a - b;
case 2:return a * b;
case 3:return a / b;
}
return -1;
}
bool dfs(vector<double> v){
int n = v.size();
if(n == 1) return abs(v.back() - 24) < eps;//浮点数和整数比较需要考虑精度问题
for(int i = 0;i < n;++i)
for(int j = 0;j < n;++j) if(i != j){//选的数不能一样
//随机选两个数
for(int k = 0;k < 4;k++){
double ans = f(v[i],v[j],k);//返回两个数运算的结果,k代表操作运算
//保留运算结果,删除选中的两个数
vector<double> tmp;
tmp.emplace_back(ans);
//删除选中的两个数
for(int l = 0;l < n;++l){
if(l != i && l != j)tmp.emplace_back(v[l]);
}
if (dfs(tmp))return true;//如果已经得到24就剪枝
}
}
return false;
}
bool judgePoint24(vector<int>& cards) {
vector<double> v;
for(auto x : cards)v.emplace_back(x);//都转换为浮点数运算
return dfs(v);
}
};
//枚举所有的可能
代码优化
- 如果除数为0进行剪枝
+ *
具备交换律,可以减少运算量
class Solution {
public:
const double eps = 1e-6;
bool dfs(vector<double> v){
int n = v.size();
if(n == 1) return abs(v.back() - 24) < eps;//浮点数和整数比较考虑精度问题
for(int i = 0;i < n;++i)
for(int j = 0;j < n;++j) if(i != j){//选的数不能一样
//随机选两个数,删除这两个数
vector<double> tmp;
for(int l = 0;l < n;++l){
if(l != i && l != j)tmp.emplace_back(v[l]);
}
double a = v[i],b = v[j];
for(int k = 0;k < 4;++k){
if(k < 2 && i > j)continue;
if(k == 0)tmp.emplace_back(a + b);
else if (k == 1)tmp.emplace_back(a * b);
else if(k == 2)tmp.emplace_back(a - b);
else if(k == 3) {
if(fabs(b) < eps)continue;
else tmp.emplace_back(a / b);
}
if(dfs(tmp))return true;
tmp.pop_back();
}
}
return false;
}
bool judgePoint24(vector<int>& cards) {
vector<double> v;
for(auto x : cards) v.emplace_back(x);//都转换为浮点数运算
return dfs(v);
}
};
//枚举所有的可能