快速计算约数的个数——从基础到高级

快速计算约数的个数——从基础到高级题目来源 欧拉计划第 12 题 高度可除的三角数 Highlydivisi 这道题我们在枚举完三角数后 最重要的是去判断何时某个三角数约数的个数大于下面我们来看下 针对计算约数的个数问题 不同的算法

题目来源:【欧拉计划第 12 题】 高度可除的三角数 Highly divisible triangular number

这道题我们在枚举完三角数后,最重要的是去判断何时某个三角数约数的个数大于 500

下面我们来看下,针对计算约数的个数问题,用不同的算法解决,逐步求得最优解

方法 1

最简单,更是非常容易理解的方法

复杂度: O ( n 2 ) \large O_{\left ( n^{2} \right )} O(n2)

主要思想:定义变量,使其在小于传入判断值的条件下从 1 开始自增,如果判断值和该变量进行模取运算后的值为 0,则说明该变量此时的值是判断值得一个约数。那么,程序计数器自增,记录下此值。循环结束后,输出计数器保存的值即为判断值约数的个数

这种方法优点除易于理解外,怕是没有优点了。缺点当然就是时间复杂度太高,一个值就需要去从 1 一直判断到该值。试想,如果数据量呈指数增长,这种方法恐怕在一般的计算机上不容易很快得到答案

实现代码如下

int check(long long n) { 
    int count = 0; long long i = 1; //注意数据范围 while (i <= n) { 
    if (n % i == 0) //成立,这说明此时 i 为 n 的一个约数 { 
    count++; //计数器自增 } i++; //继续判断下一个数字是否为 i 的约数 } return count; } 

方法 2

复杂度: O ( n ) \large O_{\left ( \sqrt{n} \right )} O(n
)

主要思想:对比可以看出,方法一和方法二差别不大,但影响最关键的是它们的复杂度,直接由 O ( n 2 ) O_{\left ( n^{2} \right )} O(n2) 降至 O ( n ) O_{\left ( \sqrt{n} \right )} O(n
)

同样,仍然是暴力枚举,只不过这里的判断条件由 i < = n 变为 i * i < = n,复杂度优化了些许。进入 for() 循环后,如果 n % i == 0 ,那么说明此时的 i 值是 n 的一个约数

大家在这里要注意的是 if...else 语句内容,这里主要解释下此处和方法一的差别

举个例子,如果 n = 4i = 2,满足 2 × 2 = 4 的条件,但此时 4 的两个约数 2 相当于一个,程序计数器只能自增 1 ,而不是 2

当然,如果进入 for() 循环后,不满足条件 i * i = n ,那么自然是两个不同的约数,此时程序计数器需要增加 2,而不是 1

int check(long long n) { 
    int count = 0; for (long long i = 1; i * i <= n; i++) { 
    if (n % i == 0) { 
    if (i * i == n) // 区别所在,重点理解 count++; else count += 2; } } return count; } 

方法 3

试除法求解

vector<int> get_divisors(int n) { 
    vector<int> res; for (int i = 1; i <= n / i; i++) if (n % i == 0) { 
    res.push_back(i); if (i != n / i) res.push_back(n / i); } sort(res.begin(), res.end()); return res; } 

LeetCode 题解思路

方法四

约数个数定理

设一个数可以表示为其素数幂的乘积,即:

n = p 1 e 1 ⋅ p 2 e 2 ⋅ ⋅ ⋅ p m e m \large n={p_{1}}^{e_{1}} \cdot {p_{2}}^{e_{2}} \cdot\cdot\cdot {p_{m}}^{e_{m}} n=p1e1p2e2pmem

则该数的约数个数为:

( e 1 + 1 ) ⋅ ( e 2 + 1 ) ⋅ ⋅ ⋅ ( e m + 1 ) \large \left ( e_{1}+1 \right )\cdot \left ( e_{2}+1 \right )\cdot \cdot \cdot \left ( e_{m}+1 \right ) (e1+1)(e2+1)(em+1)

参考代码:

#include  
     using namespace std; int main() { 
    int N, n, i, s, r; while (scanf("%d", &N) != EOF) { 
    while (N--) { 
    cin >> n; s = 1; for (i = 2; i * i <= n; i++) { 
    r = 0; while (n % i == 0) { 
    r++; n /= i; } if (r > 0) { 
    r++; s *= r; } } if (n > 1) s *= 2; cout << s; } } return 0; } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/217190.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 上午10:09
下一篇 2026年3月18日 上午10:09


相关推荐

  • python中for循环语句例子_python怎么循环1到8不要4

    python中for循环语句例子_python怎么循环1到8不要4这篇文章主要介绍了python中关于for循环使用过程中的碎碎念,需要的朋友可以参考下为什么要挑战自己在代码里不写forloop?因为这样可以迫使你去使用比较高级、地道的语法或库。文中以python为例子,讲了不少大家其实在别人的代码里都见过、但自己很少用的语法。这是一个挑战。我要你避免在任何情况下写for循环。同样的,我也要你找到一种场景——除了用for循环以外,用其他方法写都太难。请分享你的…

    2022年8月12日
    8
  • 标准网页两侧浮动广告代码,支持FF及IE

    标准网页两侧浮动广告代码,支持FF及IE点击这里使用RSS订阅本Blog:网页两侧浮动广告代码经测试支持IE、Firefox等浏览器符合标准的正常工作的对联广告lastScrollY=0;functionheartBeat(){vardiffY;if(doc

    2026年2月1日
    6
  • pytorch的安装及其在pycharm中的使用「建议收藏」

    pytorch的安装及其在pycharm中的使用「建议收藏」1.首先配置Anaconda虚拟环境在AnacondaPrompt中输入condacreate-npytorchpython==3.72.在该环境中安装pytorch因为前面已经安装了cuda10.0.130和cudnn,安装与之匹配的pytorch版本,官网中寻找,但是官网的貌似不太对,最后看的是这个回答pipinstalltorch==1.2.0torchvision==0.4.0-fhttps://download.pytorch.org/whl/torch_stab

    2022年8月25日
    10
  • 高并发下接口幂等性解决方案

    高并发下接口幂等性解决方案一 背景 nbsp nbsp nbsp nbsp nbsp nbsp nbsp 我们实际系统中有很多操作 是不管做多少次 都应该产生一样的效果或返回一样的结果 nbsp 例如 1 前端重复提交选中的数据 应该后台只产生对应这个数据的一个反应结果 2 我们发起一笔付款请求 应该只扣用户账户一次钱 当遇到网络重发或系统 bug 重发 也应该只扣一次钱 3 发送消息 也应该只发一次 同样的短信发给用户 用户会哭的 4 创建业务订单 一次业务请求只能创建一个 创建多个

    2026年3月20日
    2
  • 谈谈我对证券公司一些部门的理解——前、中、后台(转)

    谈谈我对证券公司一些部门的理解——前、中、后台(转)导语 起底金融界从业的主流选择 作者 nbsp cnfake 来源 nbsp 经管之家 原人大经济论坛 已经是 2013 年 6 月的一篇文章了 作者在文中对证券公司前中后台的各个部门的业务与职能 未来发展前景等方面进行了分析 笔者读完觉得其中大部分内容放到现在还依然适用 文中对各大部门的分析都是从作者多年经历总结出来的有感之谈 尤其是前台的 6 大部门 经纪业务总部 投资银行部 资产管理部 证券自

    2026年3月16日
    1
  • 莫比乌斯反演简单题

    莫比乌斯反演简单题莫比乌斯函数这里简述一下莫比乌斯函数 若 d 1 那么 d 1 若 d p1p2 pr r 个不同质数 且次数都为一 d 1 r 其余 d 0 莫比乌斯反演的性质性质一 莫比乌斯反演公式 f n d n d F n d f n sum d n mu d F n d 性质二 n 是积性函数性质三 设 f 是算术函数 它的和函数 F n

    2026年3月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号