C++-算24 解题思路
【Horn Studio】编程专栏: 算24 解题思路
题目
题目描述
给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。
这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。
比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们怎么都不能得到24。
这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。
比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们怎么都不能得到24。
输入
输入数据包括多行,每行给出一组测试数据,包括4个小于10个正整数。最后一组测试数据中包括4个0,表示输入的结束,这组数据不用处理。
输出
对于每一组测试数据,输出一行,如果可以得到24,输出“YES”;否则,输出“NO”。
样例输入
5 5 5 1
1 1 4 2
0 0 0 0
样例输出
YES
NO
思路
1.n 个数算 24,必有两个数先算。这两个数算的结果,和剩余 n-2 个数,就构成了 n-1 个数求 24 的问题。
2.枚举先算的两个数,以及这两个数的运算方式。
不同于以尝的DP,此题是一道dfs,如果使用暴力搜检,求出每一种得数………………(写不写得出来先不说,你能写出来,没个300000000000000000000000亿万行是不可能的!),此处不可能使用此方法。因此,我们的思路巧妙一点……
不妨我们把它随即计算,最后只剩下一个数,看这个数是不是24
(吃瓜群众:万一这个随机没有准确计算出那个正确方式,岂不还是青草池塘处处WA?)不用怕!会枚举到每个的!
代码实现起来也就很EASY了,且大部分代码改个符号CV过来,不愁没发!
代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 double a[5] = {0}; 5 #define EPS 1e-6 6 7 int isZero(double x) 8 { 9 return fabs(x) <= EPS; 10 } 11 12 int count24(double a[], int n) 13 { 14 double b[5] = {0}; 15 if (n == 1) { 16 if (isZero(a[0] - 24)) { 17 return 1; 18 } else { 19 return 0; 20 } 21 } 22 for (int i = 0; i < n - 1; i++) { 23 for (int j = i + 1; j < n; j++) { 24 int m = 0; 25 for (int k = 0; k < n; ++k) 26 if ( k != i && k != j ) 27 b[m++] = a[k]; 28 b[m] = a[i] + a[j]; 29 if ( count24(b, m + 1) ) 30 return 1; 31 b[m] = a[i] - a[j]; 32 if ( count24(b, m + 1) ) 33 return 1; 34 b[m] = a[j] - a[i]; 35 if ( count24(b, m + 1) ) 36 return 1; 37 b[m] = a[i] * a[j]; 38 if ( count24(b, m + 1) ) 39 return 1; 40 if ( !isZero(a[j]) ) { 41 b[m] = a[i] / a[j]; 42 if (count24(b, m + 1)) 43 return 1; 44 } 45 if ( !isZero(a[i]) ) { 46 b[m] = a[j] / a[i]; 47 if ( count24(b, m + 1) ) 48 return 1; 49 } 50 } 51 } 52 return 0; 53 } 54 55 int main() 56 { 57 while (true) { 58 int s = 0; 59 for (int i = 0; i < 4; i++) { 60 scanf("%lf", &a[i]); 61 s += a[i]; 62 } 63 if (s == 0) { 64 return 0; 65 } 66 if (count24(a, 4)) { 67 printf("YES\n"); 68 } else { 69 printf("NO\n"); 70 } 71 } 72 return 0; 73 }
彩蛋
:代码不多,也就五六十行而已