题目链接:https://cn.vjudge.net/problem/OpenJ_Bailian-2787
题目描述:
给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。
这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。
比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们怎么都不能得到24。
Input
输入数据包括多行,每行给出一组测试数据,包括4个小于10个正整数。最后一组测试数据中包括4个0,表示输入的结束,这组数据不用处理。
Output
对于每一组测试数据,输出一行,如果可以得到24,输出“YES”;否则,输出“NO”。
Sample Input
5 5 5 1 1 1 4 2 0 0 0 0
Sample Output
YES NO
没啥好说的,一个简单的递归
AC代码:
#include <iostream>
#include <cmath>
#define MIN 1e-6
using namespace std;
const int n = 4;
bool su24(double a[],int num)
{
cout << a[num-1] << endl;
if( num == 1) {
if(fabs(a[0] - 24) < MIN)
return true;
else
return false;
}
double b[num];
for(int i=0;i<num;i++) {
for(int j=i+1;j<num;j++) {
int k = 0;
for(int z=0;z<num;z++)
if(z != i && z!= j)
b[k++] = a[z];
// 把n个数的操作转化为n-1个数的操作 ***
b[k] = a[i]+a[j];
if( su24(b,k+1))
return true;
b[k] = a[i]-a[j];
if( su24(b,k+1))
return true;
b[k] = a[i]*a[j];
if( su24(b,k+1))
return true;
if( a[i] != 0) {
b[k] = a[j]/a[i];
if( su24(b,k+1))
return true;
}
if( a[j] != 0) {
b[k] = a[i]/a[j];
if( su24(b,k+1))
return true;
}
}
}
return false;
}
int main()
{
double a[n];
while(cin >> a[0] >> a[1] >> a[2] >> a[3] && a[0]!=0 && a[1]!=0 && a[2]!=0 && a[3]!=0)
{
if( su24(a,n))
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}