时间限制:6000
内存限制:65536
题目描述
给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于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
思路:直接深搜,把问题简化一下 变成第一次两个算 第二次n-2个数算 这n-2个数又选两个算......直到算到剩下1个数的时候 这一个数也就是答案了。把问题化成多个小问题 直到不能再化为止。
上code
不准直接抄!!!
#include <iostream>
#include <cmath>
#define e 1e-6
using namespace std;
/*/我们把问题简化一下 变成第一次两个算 第二次n - 2个数算 这n - 2个数又选两个算......
直到算到剩下1个数的时候 这一个数也就是答案了。把问题化成多个小问题 直到不能再化为止*/
bool dfs(double a[], int n)//dfs深度优先搜索,简称深搜
{
if (n == 1)
{
if (fabs(a[0] - 24) <= e) //浮点数的等价比价
return true;
else
return false;
}
double b[5];
//把这个没算的数放b数组里 (这次两个数的结果也放b里) 相当于b的个数是n-1
for (int i = 0; i < n - 1; i++)
{
for (int j = i + 1; j < n; j++)
//两成for循环 找出所有的两个数的组合
{
int m = 0; //表示b数组里的个数
for (int k = 0; k < n; k++)
//遍历a 把当前不作为算数的数放b里
{
if (k != i && k != j)
b[m++] = a[k];
}
//然后就开始四则运算的实验了
b[m] = a[i] + a[j];
if (dfs(b, m + 1))
return true;
b[m] = a[i] - a[j]; //减有两种
if (dfs(b, m + 1))
return true;
b[m] = a[j] - a[i];
if (dfs(b, m + 1))
return true;
b[m] = a[i] * a[j];
if (dfs(b, m + 1))
return true;
if (a[j] != 0) //排除分母为0的情况
{
b[m] = a[i] / a[j];
if (dfs(b, m + 1))
return true;
}
if (a[i] != 0)
{
b[m] = a[j] / a[i];
if (dfs(b, m + 1))
return true;
}
}
}
return false;
}
int main()
{
double a[5];
for (int i = 0; i < 4; i++)
cin >> a[i];
if (dfs(a, 4))
cout << "YES";
else
cout << "NO";
return 0;//养成好习惯
}
作者制作不易,喜欢就 赶紧用你发财的小手点个赞,关注一下吧!