递归算法实例应用(五)

简介: 递归算法实例应用(五):(POJ 2787)算24

递归算法实例应用(五)

算24 (POJ 2787)

Description

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




算法思想:

同样拿到题之后呢,首先第一个想法依旧是能否将问题分解为规模更小的子问题,然后利用递归解决。

对于问题解决的第一步而言,普遍想法是,先找两个数进行一种加、减、乘、除运算,再将该结果与剩下的n-2个数进行运算,那么此时,问题规模就变为了n-1,因此本题就转变为一个递归问题。

再考虑递归的次数,我们从第一步的初始状态开始不断递归判断是否能满足题设要求,当以此为初始条件均不能满足题设要求时,应继续判定下一初始条件,所以我们应枚举所有可能的第一步的初始状态,即:枚举所有可能的两个数的组合。再以此为初始条件进行递归判断是否为解。

其次考虑递归的边界条件,基于前几题的求边界条件思想,本题的边界情况十分明显,即当问题规模递归减少为1时,仅有一个数,判断与24是否相等,若相等则应返回true,表明找到一组解,若不相等应返回false,表明本次递归的初始条件不能满足题设要求。

详细说明关于在递归时数据的处理:

  1. 选出两个数作为初始条件进行加、减、乘、除运算,选取时应取遍所有可能的组合,可通过二重循环实现。
  2. 将这两个数(a和b)的运算结果与余下的n-2个数存起来,共n-1个数,存入一个数组中,作为中间变量,在以该中间变量数组进行递归,依次判断a+b、a-b、b-a、a*b、a/b、b/a六种情况,在除法运算中,应保证除数不为0;此时的递归为将临时变量b里的n-1个数来算24,判断是否可以满足题设要求。问题的递归主体及关键也在这里。




代码逻辑:

依据上述算法思想,不难想出应设置一个初始数组存储题设输入的一组数据;因为本题中设计除法相关操作,所以数据可能为浮点类型,但是由于浮点数在计算机中存储采用IEE754标准,存在精度丢失问题,所以对于浮点类型数据是否为0的判定不能使用“==”来判定,所以,还应定义一个函数来实现对浮点数是否为0的一个判断。

  1. 在C语言中,进行浮点数为0判断时,一般考虑判断该数的绝对值是否小于一个极小值ε,通常ε选10^-6。

    代码如下:

    #define ESP 1e-6
    
    bool isZero(double num) {
        return fabs(num) <= ESP;
    }
  2. 由上述算法思想中分析,设递归函数定义为,bool count24(double a[], int n),即:对有n个元素的a组数据进行算24操作。

    • 首先进入递归函数时应判断是否满足边界条件,即,当问题规模n=1时,判断该数是否等于24。
    • 在递归主体中,首先声明中间变量数组b,用于存储剩下的n-1个数以实现递归。
    • 通过枚举每一种可能的初始条件,以期寻求所有可能的解。
    • 每找到两个数后,将其与的n-2个数存入中间变量数组b中,再对这两个数进行算法思想中第二点所分析的6种情况进行计算。
    • 假设以a+b为例,其代码可描述为:

      b[m] = a[i] + a[j];
      if (count24(b, m + 1))
          return true;
    • 假设以a/b为例,其中b不为0,其代码可描述为:

      if (!isZero(a[j])) {
          b[m] = a[i] / a[j];
          if (count24(b, m + 1))
              return true;
      }
  3. 本题思想逻辑较前几题几乎并无不同,但在代码实现上有更大的难度,主要是对不同的情况做不同的递归处理,同时对于数据的处理也应考虑递归时数据作用域的不同对函数运算结果过的影响。比如用于存储题设输入元素的数组a,应为全局变量,因为在递归处理时,我们以中间变量b来进行运算,但同时也用到了数组a来为b进行赋值。所以在每一层递归中都用到了该变量,与递归层级无关,所以设置为全局变量能更好的进行代码的编写;或者将原始数组a作为形参传入递归函数,但是由于递归操作本来就对函数调用栈有较高的占用率,若再增加没有必要的形参数量,无疑是为函数调用栈带来了更大的负载。
  4. 至此,递归章节将告一段落,以上数题基本涵盖了递归在时间和空间复杂度要求不高的情况下能仅用递归能解决问题的几种基本问题模型。




代码整合:

//
// Created by Ss1Two on 2023/1/18.
//

#include "stdio.h"
#include "stdbool.h"
#include "math.h"

#define ESP 1e-6 //

//判断浮点数num是否为0
bool isZero(double num) {
    return fabs(num) <= ESP;
}

//存储题设输入的原始数据
double a[5];

//把数组a中的n个元素进行算24判断
bool count24(double a[], int n) {

    //递归边界条件判定
    if (n == 1) {
        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;// m作为处理剩下的n-2个数时的下标
            for (int k = 0; k < n; k++) {
                //将非初始条件之外的n-2个数据存入中间变量b数组中
                if (k != i && k != j)
                    b[m++] = a[k];
            }

            //将初始条件的两个值做加法运算,并存入中间变量b数组中
            //其中m+1==n-1
            b[m] = a[i] + a[j];

            //此时问题规模减一,即将b数组中的n-1个数,进行算24判断。
            //情况1:a + b
            if (count24(b, m + 1))
                return true;

            //情况2:a - b
            b[m] = a[i] - a[j];
            if (count24(b, m + 1))
                return true;

            //情况3:b - a
            b[m] = a[j] - a[i];
            if (count24(b, m + 1))
                return true;


            //情况4:a * b
            b[m] = a[i] * a[j];
            if (count24(b, m + 1))
                return true;


            //情况5:a / b ,其中b!=0
            if (!isZero(a[j])) {
                b[m] = a[i] / a[j];
                if (count24(b, m + 1))
                    return true;
            }

            //情况6:b / a ,其中a!=0
            if (!isZero(a[i])) {
                b[m] = a[j] / a[i];
                if (count24(b, m + 1))
                    return true;
            }
        }
    }
    return false;
}

int main() {
    while (true) {
        for (int i = 0; i < 4; i++) {
            scanf("%lf", &a[i]);
        }
        if (isZero(a[0]))break;
        if (count24(a, 4))
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}


Created by Ss1Two on 2023/01/18

目录
相关文章
|
3月前
|
存储 监控 JavaScript
基于布隆过滤器的 Node.js 算法在局域网电脑桌面监控设备快速校验中的应用研究
本文探讨了布隆过滤器在局域网电脑桌面监控中的应用,分析其高效空间利用率、快速查询性能及动态扩容优势,并设计了基于MAC地址的校验模型,提供Node.js实现代码,适用于设备准入控制与重复数据过滤场景。
188 0
|
2月前
|
运维 监控 JavaScript
基于 Node.js 图结构的局域网设备拓扑分析算法在局域网内监控软件中的应用研究
本文探讨图结构在局域网监控系统中的应用,通过Node.js实现设备拓扑建模、路径分析与故障定位,提升网络可视化、可追溯性与运维效率,结合模拟实验验证其高效性与准确性。
232 3
|
2月前
|
机器学习/深度学习 资源调度 算法
遗传算法模型深度解析与实战应用
摘要 遗传算法(GA)作为一种受生物进化启发的优化算法,在复杂问题求解中展现出独特优势。本文系统介绍了GA的核心理论、实现细节和应用经验。算法通过模拟自然选择机制,利用选择、交叉、变异三大操作在解空间中进行全局搜索。与梯度下降等传统方法相比,GA不依赖目标函数的连续性或可微性,特别适合处理离散优化、多目标优化等复杂问题。文中详细阐述了染色体编码、适应度函数设计、遗传操作实现等关键技术,并提供了Python代码实现示例。实践表明,GA的成功应用关键在于平衡探索与开发,通过精心调参维持种群多样性同时确保收敛效率
|
2月前
|
机器学习/深度学习 边缘计算 人工智能
粒子群算法模型深度解析与实战应用
蒋星熠Jaxonic是一位深耕智能优化算法领域多年的技术探索者,专注于粒子群优化(PSO)算法的研究与应用。他深入剖析了PSO的数学模型、核心公式及实现方法,并通过大量实践验证了其在神经网络优化、工程设计等复杂问题上的卓越性能。本文全面展示了PSO的理论基础、改进策略与前沿发展方向,为读者提供了一份详尽的技术指南。
粒子群算法模型深度解析与实战应用
|
2月前
|
机器学习/深度学习 算法 安全
小场景大市场:猫狗识别算法在宠物智能设备中的应用
将猫狗识别算法应用于宠物智能设备,是AIoT领域的重要垂直场景。本文从核心技术、应用场景、挑战与趋势四个方面,全面解析这一融合算法、硬件与用户体验的系统工程。
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
深度学习模型、算法与应用的全方位解析
深度学习,作为人工智能(AI)的一个重要分支,已经在多个领域产生了革命性的影响。从图像识别到自然语言处理,从语音识别到自动驾驶,深度学习无处不在。本篇博客将深入探讨深度学习的模型、算法及其在各个领域的应用。
917 3
|
4月前
|
机器学习/深度学习 人工智能 算法
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用
AI-Compass 强化学习模块:理论到实战完整RL技术生态,涵盖10+主流框架、多智能体算法、游戏AI与金融量化应用
|
4月前
|
存储 监控 安全
企业上网监控系统中红黑树数据结构的 Python 算法实现与应用研究
企业上网监控系统需高效处理海量数据,传统数据结构存在性能瓶颈。红黑树通过自平衡机制,确保查找、插入、删除操作的时间复杂度稳定在 O(log n),适用于网络记录存储、设备信息维护及安全事件排序等场景。本文分析红黑树的理论基础、应用场景及 Python 实现,并探讨其在企业监控系统中的实践价值,提升系统性能与稳定性。
156 1
|
3月前
|
算法 数据可视化
matlab版本粒子群算法(PSO)在路径规划中的应用
matlab版本粒子群算法(PSO)在路径规划中的应用
|
4月前
|
存储 监控 算法
公司员工泄密防护体系中跳表数据结构及其 Go 语言算法的应用研究
在数字化办公中,企业面临员工泄密风险。本文探讨使用跳表(Skip List)数据结构优化泄密防护系统,提升敏感数据监测效率。跳表以其高效的动态数据处理能力,为企业信息安全管理提供了可靠技术支持。
122 0

热门文章

最新文章