Twenty-four point
Description:
Given four numbers, can you get twenty-four through the addition, subtraction, multiplication, and division? Each number can be used only once.
Input
The input consists of multiple test cases. Each test case contains 4 integers A, B, C, D in a single line (1 <= A, B, C, D <= 13).
Output
For each case, print the “Yes” or “No”. If twenty-four point can be get, print “Yes”, otherwise, print “No”.
Sample Input
2 2 3 9
1 1 1 1
5 5 5 1
Sample Output
Yes
No
Yes
Hint
For the first sample, (2/3+2)*9=24.
题目大意:
没什么可以说的了,求24点,大家都懂。注意一下由于会出现小数,读数据以及运算的时候用double类型,最后结果在极小误差范围内等于24即可。
解题思路:
1.只有4个数,4种运算法则,总的情况数不多。因此可以采用暴力搜素的方式找结果。
2.从运算法则的角度上来看:对于1个数,那运算结果只能是这个数。对于2个数a,b,运算的结果可以有: a+b , a-b ,b-a , a*b , a/b , b/a (其中最后两种需要先判断分母不为0)
3.对于3个及以上的数,我们就先对两个数进行运算,在将结果与剩下的数进行预算,直到只剩下一个数。
4.先对两个数运算的时候,首先要注意运算完毕以后是需要还原的。因为最后的结果可能不是这两个数先运算。(比如 结果(a+c)*(b+d),如果先对a和b运算但是不还原的话,就会搜不到这个结果了)其次递归调用的时候,由于每进入下一层,表示未运算的数变少了,是需要将剩下的数提前到前面的位置的。
源代码:
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<math.h>
#include<algorithm>
#include<vector>
using namespace std;
double num[4];
bool flag;
void dfs(int n) {
if (flag)
return ;
if (n == 1 && fabs(num[0] - 24.0) < 1e-9) {
flag = true;
return ;
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
double a = num[i]; //暂存两个选择的运算数
double b = num[j];
num[j] = num[n - 1]; //缩小范围,将后面的未运算数提前,开始依次测试
num[i] = a + b;
dfs(n - 1);
num[i] = a - b;
dfs(n - 1);
num[i] = b - a;
dfs(n - 1);
num[i] = a*b;
dfs(n - 1);
if (a) {
num[i] = b / a;
dfs(n - 1);
}
if (b) {
num[i] = a / b;
dfs(n - 1);
}
num[i] = a;
num[j] = b;
}
}
}
int main() {
while (~scanf("%lf%lf%lf%lf", &num[0], &num[1], &num[2], &num[3])) {
flag = false;
dfs(4);
if (flag)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}