《程序设计与算法(二)算法基础》《第二周 递归》算24 2787

2787:算24

总时间限制: 
3000ms
 
内存限制: 
65536kB
描述
给出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
/*
http://bailian.openjudge.cn/practice/2787/
2787:算24
*/
#include<iostream>
#include<cmath>
using namespace std;

#define EPS 1e-6

double a[5];

bool IsZero(double x)
{
    //if (fabs(x) < EPS)
    //    return true;
    //else
    //    return false;
    return fabs(x) <= EPS;
}

bool count24(double a[],int n )
{//用数组 a 里的 n 个数,计算 24
    if (1 == n)
    {
        if (IsZero(a[0] - 24))
            return true;
        else
            return false;
    }
    double b[5];
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = i + 1; j < n; j++)
        {
            // 枚举两个数的组合
            int m = 0;
            for (int k = 0; k < n; k++) // 还剩下 m 个数 , m = n 2
            {
                if (k != i && k != j)
                    b[m++] = a[k]; // 把其余数放入 b
            }
            b[m] = a[i] + a[j];
            /* pay attention at here */
            if (count24(b, m + 1))
                return true;
            b[m] = a[i] - a[j];
            if (count24(b, m + 1))
                return true;
            b[m] = a[j] - a[i];
            if (count24(b, m + 1))
                return true;
            b[m] = a[i] * a[j];
            if (count24(b, m + 1))
                return true;
            // a[i] != 0 can divide
            if (!IsZero(a[i]))
                b[m] = a[j] / a[i];
                if (count24(b, m + 1))
                    return true;
            if (!IsZero(a[j]))
                b[m] = a[i] / a[j];
                if (count24(b, m + 1))
                    return true;
                
        }
    }
    // can not omit
    // !!! pay attention
    // 如果枚举了数组a[]中的所有可能,都算不出24,不能return true,
    // 说明 当前这一组数,是算不出24的,return false,尝试其他的可能组合
    return false;
}
int main()
{
    //如何不停的读入输入的4个数
    int i = 0;
    while (true)
    {
        double sum = 0;

        for (i = 0; i < 4; i++)
        {
            cin >> a[i];
            sum += a[i]; // 0 0 0 0 终止,输入都是正整数
        }
        if (IsZero(sum))
            break;
        bool result = count24(a, 4);
        if (result)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;

}

 

posted @ 2019-09-07 13:48  清风oo  阅读(257)  评论(0编辑  收藏  举报