你有 4 张写有 1 到 9 数字的牌。你需要判断是否能通过 *,/,+,-,(,) 的运算得到 24。
示例 1:
输入: [4, 1, 8, 7]
输出: True
解释: (8-4) * (7-1) = 24
示例 2:
输入: [1, 2, 1, 2]
输出: False
注意:
- 除法运算符 / 表示实数除法,而不是整数除法。例如 4 / (1 - 2/3) = 12 。
- 每个运算符对两个数进行运算。特别是我们不能用 - 作为一元运算符。例如,[1, 1, 1, 1] 作为输入时,表达式 -1 - 1 - 1 - 1 是不允许的。
- 你不能将数字连接在一起。例如,输入为 [1, 2, 1, 2] 时,不能写成 12 + 12 。
对于数字a,b存在6种运算:
那么每次都选出2个数字进行6种运算操作
注意:
le-6是浮点计算的精度误差,这里判断误差是否小于1e-6,这样就是正确结果
class Solution {
public:
bool judgePoint24(vector<int>& nums) {
double a = nums[0], b = nums[1], c = nums[2], d = nums[3];
return judgePoint24_4(a,b,c,d);
}
//第1轮:从4个数字中选2个进行六次可能的操作
bool judgePoint24_4(double a, double b, double c, double d){
return judgePoint24_3( a + b, c, d)|| //a,b
judgePoint24_3( a * b, c, d)||
judgePoint24_3( a - b, c, d)||
judgePoint24_3( b - a, c, d)||
judgePoint24_3( a / b, c, d)||
judgePoint24_3( b / a, c, d)||
judgePoint24_3( a + c, b, d)|| //a,c
judgePoint24_3( a * c, b, d)||
judgePoint24_3( a - c, b, d)||
judgePoint24_3( c - a, b, d)||
judgePoint24_3( a / c, b, d)||
judgePoint24_3( c / a, b, d)||
judgePoint24_3( a + d, b, c)|| // a,d
judgePoint24_3( a * d, b, c)||
judgePoint24_3( a - d, b, c)||
judgePoint24_3( d - a, b, c)||
judgePoint24_3( a / d, b, c)||
judgePoint24_3( d / a, b, c)||
judgePoint24_3( b + c, a, d)|| // b,c
judgePoint24_3( b * c, a, d)||
judgePoint24_3( b - c, a, d)||
judgePoint24_3( c - b, a, d)||
judgePoint24_3( b / c, a, d)||
judgePoint24_3( c / b, a, d)||
judgePoint24_3( b + d, a, c)|| // b,d
judgePoint24_3( b * d, a, c)||
judgePoint24_3( b - d, a, c)||
judgePoint24_3( d - b, a, c)||
judgePoint24_3( b / d, a, c)||
judgePoint24_3( d / b, a, c)||
judgePoint24_3( c + d, a, b)|| // c,d
judgePoint24_3( c * d, a, b)||
judgePoint24_3( c - d, a, b)||
judgePoint24_3( d - c, a, b)||
judgePoint24_3( c / d, a, b)||
judgePoint24_3( d / c, a, b);
}
//第2轮:从3个数字中选2个进行六次可能的操作
bool judgePoint24_3(double a, double b, double c){
return judgePoint24_2( a + b, c) || // a,b
judgePoint24_2( a * b, c) ||
judgePoint24_2( a - b, c) ||
judgePoint24_2( b - a, c) ||
judgePoint24_2( a / b, c) ||
judgePoint24_2( b / a, c) ||
judgePoint24_2( a + c, b) || // a,c
judgePoint24_2( a * c, b) ||
judgePoint24_2( a - c, b) ||
judgePoint24_2( c - a, b) ||
judgePoint24_2( a / c, b) ||
judgePoint24_2( c / a, b) ||
judgePoint24_2( b + c, a) || // b,c
judgePoint24_2( b * c, a) ||
judgePoint24_2( b - c, a) ||
judgePoint24_2( c - b, a) ||
judgePoint24_2( b / c, a) ||
judgePoint24_2( c / b, a) ;
}
//第3轮:从2个数字中选2个进行六次可能的操作
bool judgePoint24_2(double a, double b){
return judgePoint24_1( a + b ) ||
judgePoint24_1( a * b ) ||
judgePoint24_1( a - b ) ||
judgePoint24_1( b - a ) ||
judgePoint24_1( a / b ) ||
judgePoint24_1( b / a ) ;
}
//第4轮:对最终结果进行24判定
bool judgePoint24_1(double result){
// return result == 24.0; //测试用例[3,3,8,8]不会通过:8/(3-8/3)=24
// le-6是浮点计算的精度误差,这里判断误差小于1e-6,这样就是正确结果
return abs(result - 24) < 1e-6;
}
};
class Solution {
public:
bool judgePoint24(vector<int>& nums) {
if(nums.size()!=4) return false;
vector<double> vec;
for(int i=0; i<nums.size(); i++)
vec.push_back(nums[i]);
return dfs(vec);
}
bool dfs(vector<double>& vec){
if(vec.size() == 0) return false;
if(vec.size() == 1){
return abs(vec[0]-24) < 1e-6;
}
for(int i=0; i<vec.size(); i++){
for(int j=i+1; j<vec.size(); j++){
//每次取出两个数进行6种运算,将其余数都保存
vector<double> newvec;
double a = vec[i], b = vec[j], r;
for( int k=0; k<vec.size(); k++){
if(k!=i&&k!=j) newvec.push_back(vec[k]);
}
//每次尝试都将运算结果保存,如果尝试失败注意还原操作
for(int k=0; k<6; k++){
if(k==0){
r = a + b;
}else if(k==1){
r = a - b;
}else if(k==2){
r = b - a;
}else if(k==3){
r = a * b;
}else if(k==4){
if( b == 0) continue;
r = a / b;
}else if(k==5){
if( a == 0) continue;
r = b / a;
}
newvec.push_back(r);
if( dfs(newvec) ) return true;
newvec.pop_back(); // 还原操作,删除最后一个元素即刚刚的运算结果
}
}
}
return false;
}
};