博客
关于我
bzoj 3629: [JLOI2014]聪明的燕姿
阅读量:258 次
发布时间:2019-03-01

本文共 1965 字,大约阅读时间需要 6 分钟。

求所有约数和等于S的数

在这个问题中,我们需要找出所有满足约数和等于给定值S的正整数。为了高效解决这个问题,我们采用了一种基于深度优先搜索(DFS)的方法。这种方法能够快速找到所有符合条件的数。

方法思路

首先,我们需要理解约数和的概念。一个数的约数和是指其所有正约数的和。例如,6的约数有1、2、3、6,约数和为12。我们的目标是找到所有这样的数,使得它们的约数和等于S。

为了实现这一点,我们使用了以下方法:

  • 预处理质数:首先,我们生成一个质数列表,这些质数将用于构造可能的数。
  • 深度优先搜索:通过递归的方法,尝试所有可能的质因数分解,计算每个可能数的约数和。
  • 剪枝优化:为了避免重复计算,我们在搜索过程中使用了一些剪枝技巧,确保每个路径只计算一次。
  • ###代码实现以下是实现该方法的C++代码:

    #include 
    #include
    #include
    #include
    #include
    #include
    #include
    using namespace std;#define LL long longint prime[100010], pr = 0;int sqrts, ans[1000010], n;bool v[100010];void pre() { memset(v, true, sizeof(v)); for (int i = 2; i <= 100000; ++i) { if (v[i]) { prime[++pr] = i; for (int j = 1; j <= pr && i * prime[j] <= 100000; ++j) { v[i * prime[j]] = false; if (i % prime[j] == 0) break; } } }}bool isprime(int x) { if (x <= 100000) return v[x]; int tmp = sqrt(x); for (int i = 1; prime[i] <= tmp; ++i) { if (x % prime[i] == 0) return false; } return true;}void cal(int last, int tot, int num) { if (tot == 1) { ans[++n] = num; return; } if (tot - 1 > sqrts && isprime(tot - 1)) { ans[++n] = (tot - 1) * num; } for (int i = last + 1; prime[i] <= sqrts; ++i) { int tmp = 1, t = prime[i]; for (int j = 1; tmp + t <= tot; ++j) { tmp += t; t *= prime[i]; if (tot % tmp == 0) { cal(i, tot / tmp, num * (t / prime[i])); } } }}int main() { int S; pre(); while (scanf("%d", &S) != EOF) { sqrts = sqrt(S); n = 0; cal(0, S, 1); sort(ans + 1, ans + n + 1); for (int i = 1; i <= n; ++i) { cout << ans[i] << endl; } }}

    代码解释

  • 预处理质数pre()函数用于生成质数列表。我们使用了一个标记数组v,初始时所有位置都被标记为true,表示这些数是合数。然后,我们从2开始遍历,标记出所有质数,并更新质数列表。

  • 检查是否为质数isprime()函数用于检查一个数是否为质数。对于小于100000的数,直接使用预处理的质数列表;对于大于100000的数,通过试除法检查。

  • 深度优先搜索cal()函数是递归函数,用于生成所有可能的数。我们从给定的质因数分解开始,逐步构造数,并计算其约数和。如果约数和等于目标值S,则将该数记录下来。

  • 剪枝优化:在递归过程中,如果当前分解路径已经超出目标值,或者当前分解已经超过了预处理的质数范围,我们就停止递归,避免重复计算。

  • 排序和输出:在主函数中,我们对生成的结果进行排序,并按照要求输出结果。

  • 适用场景

    这种方法适用于处理较小的S值,能够快速生成所有约数和等于S的数。对于较大的S值,可能需要进行优化,以减少计算时间。

    转载地址:http://gdza.baihongyu.com/

    你可能感兴趣的文章
    ThreadLocal线程内部存储类
    查看>>
    thinkphp 常用SQL执行语句总结
    查看>>
    Oracle:ORA-00911: 无效字符
    查看>>
    Text-to-Image with Diffusion models的巅峰之作:深入解读 DALL·E 2
    查看>>
    Tensorflow.python.framework.errors_impl.ResourceExhaustedError:无法分配内存[操作:AddV2]
    查看>>
    TCP基本入门-简单认识一下什么是TCP
    查看>>
    tableviewcell 中使用autolayout自适应高度
    查看>>
    Symbolic Aggregate approXimation(SAX,符号聚合近似)介绍-ChatGPT4o作答
    查看>>
    Orcale表被锁
    查看>>
    svn访问报错500
    查看>>
    sum(a.YYSR) over (partition by a.hy_dm) 不需要像group by那样需要分组函数。方便。
    查看>>
    ORCHARD 是什么?
    查看>>
    Struts2中使用Session的两种方法
    查看>>
    STM32工作笔记0032---编写跑马灯实验---寄存器版本
    查看>>
    order by rand()
    查看>>
    SSM(Spring+SpringMvc+Mybatis)整合开发笔记
    查看>>
    Orderer节点启动报错解决方案:Not bootstrapping because of 3 existing channels
    查看>>
    org.apache.axis2.AxisFault: org.apache.axis2.databinding.ADBException: Unexpected subelement profile
    查看>>
    sql查询中 查询字段数据类型 int 与 String 出现问题
    查看>>
    org.apache.commons.beanutils.BasicDynaBean cannot be cast to ...
    查看>>