博客
关于我
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/

    你可能感兴趣的文章
    Python 数据结构与算法详解
    查看>>
    Python 数据采集、清洗、整理、分析以及可视化实战
    查看>>
    Python 数据预处理
    查看>>
    python 文件类型检测 linux和windows都可以用
    查看>>
    Python多处理池,加入;不等待继续?
    查看>>
    Python 无法安装包
    查看>>
    python 日历小部件 - 返回用户选择的日期
    查看>>
    Python 日志管理封装
    查看>>
    python 时间函数小总结
    查看>>
    Python 是否优化尾递归?
    查看>>
    Python 更新set
    查看>>
    Python 最强 IDE 详细使用指南!
    查看>>
    Python 有一个不可变的列表吗?
    查看>>
    Python 机器学习入门之 pandas 的使用
    查看>>
    Python 机器学习实战
    查看>>
    python 杀死子进程_subprocess.popen.kill杀死所有子进程
    查看>>
    Python 条件语句与循环结构详解
    查看>>
    Python 条件运算符解决方法如何工作?
    查看>>
    python 枚举类型
    查看>>
    Python 查询 Mongodb数据库
    查看>>