计算结果等于24

这篇博客介绍了一个编程问题,即如何通过加减乘除运算将4个正整数组合成一个表达式,使得结果为24。提供了一个C++代码示例来解决这个问题,通过全排列和递归计算来检查所有可能的组合。文章以输入样例和输出样例说明了算法的正确性,并强调了除法操作中避免除以零的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给出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

 

代码

#include <stdio.h>

#include <iostream>

#include <cmath>

#include <string.h>

using namespace std;

 

double a[4];

int c[4];

int b[4];

char cal_opt[4] = {'+', '-', '*', '/'};

bool flag = false;

bool selected[4];

bool visited[4];

 

double cal(double a, double b, char opt) {

    if (opt == cal_opt[0])

        return a + b;

    else if (opt == cal_opt[1])

        return a - b;

    else if (opt == cal_opt[2])

        return a * b;

    else if (opt == cal_opt[3])

        return a / b;

    return 0.0;

}

 

void calculate(int count) {

    double result;

    if (count == 1) {

        for (int i = 0; i < 4; ++i) {

            if (!visited[i]) {

                result = a[i];

                break;

            }

        }

        if (fabs(result - 24.0) < 0.000001) {

            cout << "YES" << endl;

            flag = true;

        }

        return;

    }

    

    double left, right;

    for (int i = 0; i < 3; ++i) {

        if (visited[i])

            continue;

        for (int k = i + 1; k < 4; ++ k) {

            if (visited[k])

                continue;

            left = a[i];

            right = a[k];

            for (int j = 0; j < 4; ++j) {

                if (a[k] == 0 && j == 3) // 除法不能除0

                    continue;

                result = cal(a[i], a[k], cal_opt[j]);

                a[i] = result;

                visited[k] = 1;

                calculate(--count);

                if (flag)

                    goto here;

                

                a[i] = left;

                a[k] = right;

                visited[k] = 0;

                ++count;

            }

        }

    }

here:

    return;

}

 

int main() {

    while (true) {

        bool is_end = true;

        for (int i = 0; i < 4; ++i) {

            cin >> b[i];

            if (b[i] != 0)

                is_end = false;

        }

        if (is_end)

            break;

        

        // 生成一个全排列

        memset(selected, 0, sizeof selected);

        memset(visited, 0, sizeof visited);

        flag = false;

        for (int i = 0; i < 4; ++i) {

            if (selected[i])

                continue;

            selected[i] = 1;

            a[0] = b[i];

            for (int j = 0; j < 4; ++j) {

                if (selected[j])

                    continue;

                selected[j] = 1;

                a[1] = b[j];

                for (int k = 0; k < 4; ++k) {

                    if (selected[k])

                        continue;

                    selected[k] = 1;

                    a[2] = b[k];

                    for (int l = 0; l < 4; ++l) {

                        if (selected[l])

                            continue;

                        selected[l] = 1;

                        a[3] = b[l];

                        calculate(4);

                        if (flag)

                            goto here;

                        selected[l] = 0;

                    }

                    selected[k] = 0;

                }

                selected[j] = 0;

            }

            selected[i] = 0;

        }

    here:

        if (!flag)

            cout << "NO" << endl;

    }

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值