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

    你可能感兴趣的文章
    Node.js 异步模式浅析
    查看>>
    node.js 怎么新建一个站点端口
    查看>>
    Node.js 文件系统的各种用法和常见场景
    查看>>
    Node.js 的事件循环(Event Loop)详解
    查看>>
    node.js 简易聊天室
    查看>>
    Node.js 线程你理解的可能是错的
    查看>>
    Node.js 调用微信公众号 API 添加自定义菜单报错的解决方法
    查看>>
    node.js 配置首页打开页面
    查看>>
    node.js+react写的一个登录注册 demo测试
    查看>>
    Node.js中环境变量process.env详解
    查看>>
    Node.js之async_hooks
    查看>>
    Node.js升级工具n
    查看>>
    Node.js卸载超详细步骤(附图文讲解)
    查看>>
    Node.js基于Express框架搭建一个简单的注册登录Web功能
    查看>>
    Node.js安装与配置指南:轻松启航您的JavaScript服务器之旅
    查看>>
    Node.js安装及环境配置之Windows篇
    查看>>
    Node.js安装和入门 - 2行代码让你能够启动一个Server
    查看>>
    node.js安装方法
    查看>>
    Node.js官网无法正常访问时安装NodeJS的方法
    查看>>
    Node.js的循环与异步问题
    查看>>