NOI: 算24

题目大意

在这里插入图片描述

解题思路

(1) 由于有括号,因此我们可以不考虑运算符之间的优先级。
(2) 以现有数字的两两组合不同运算为分支进行深搜,每次组合后减少一个数字,用0占位,数字0不再参与组合。
(3) 递归出口,两两组合,直到最终组合到一个数字。

代码

#include<iostream>
using namespace std;

int flag;
double abs(double a)
{
    if(a > 0)
        return a;
    return -a;
}
void dfs(double a, double b, double c, double d)
{
    if(flag)
        return;
    if(abs(a+b+c+d-24.0) < 10e-4)
    {
        flag = 1;
        return;
    }
    double arr[4] = {a, b, c, d};
    for(int i=0; i<4; i++)
    {
        for(int j=0; j<4; j++)
        {
            double brr[4];
            if(i!=j && arr[i] != 0 && arr[j] != 0)
            {
                double tmp1 = arr[i]+arr[j];
                for(int t=0; t<4; t++)
                    brr[t] = arr[t];
                brr[i] = tmp1;
                brr[j] = 0;
                dfs(brr[0], brr[1], brr[2], brr[3]);

                tmp1 = arr[i]-arr[j];
                for(int t=0; t<4; t++)
                    brr[t] = arr[t];
                brr[i] = tmp1;
                brr[j] = 0;
                dfs(brr[0], brr[1], brr[2], brr[3]);

                tmp1 = arr[i]*arr[j];
                for(int t=0; t<4; t++)
                    brr[t] = arr[t];
                brr[i] = tmp1;
                brr[j] = 0;
                dfs(brr[0], brr[1], brr[2], brr[3]);

                tmp1 = arr[i]/arr[j];
                for(int t=0; t<4; t++)
                    brr[t] = arr[t];
                brr[i] = tmp1;
                brr[j] = 0;
                dfs(brr[0], brr[1], brr[2], brr[3]);
            }
        }
    }
}
int main()
{
    double a, b, c, d;
    while(cin >> a >> b >> c >> d && a)
    {
        flag = 0;
        dfs(a, b, c, d);
        if(flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    return 0;
}

知识点

  • 声明在函数内部的数组是每个函数独有的,如上方的arr[4]
  • dfs(int x, int y)通过dfs(b[0], b[1])调用不会改变b[0]b[1]的值。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值