11.14 晚自习 为什么求约数个数、判断是否是质数都只用遍历到sqrt就行了

发布于 2024-11-14  89 次阅读


在寻找一个数的约数时,只需要循环到该数的平方根,这是因为约数是成对出现的

具体来说,如果 n 是一个正整数,并且 d 是 n 的一个约数,那么可以表示为:

n=d×k

其中 k 也是 n 的一个约数。根据这个关系,如果 d 小于或等于 n​,那么 k 必然大于或等于 n​,反之亦然

所以,我们可以知道,每找到一个小于 n​ 的约数 d,就可以立即找到一个大于 n 的约数 k

这样确实可以提高工作效率,但是你要考虑的东西更多了

计数约数

  • 如果 a 是 n 的约数,那么:
    • 如果 a 和 b(b是对应的另一个约数)不相等,约数的计数增加 2
    • 如果 a 和 b 相等(这发生在是n的完全平方数时),约数的计数增加 1
 for (int i = 1; i <= sqrt(n); i++) {
        if (n % i == 0) { // 如果 i 是 n 的约数
            printf("%d ", i); // 输出约数 i
            if (i != n / i) { // 避免重复输出平方根
                printf("%d ", n / i); // 还得输出配对约数 n / i
            }

看吧,还不如直接i <n 简单粗暴

同时,这样做需要考虑等于sqrt的情况


再看看质数的判断

这里就可以简单粗暴地直接用sqrt了

原因其实也和约数有关

如果一个数 n 不是质数,那么它必定有至少一个约数 a ,又因为约数成对存在,只要不是质数,那么小于等于sqrt的约数个数就等于大于等于sqrt的约数个数

只要sqrt之内(含sqrt)有一个数字 i 满足 n%i==0,那么n就肯定不是质数

同时,这里当然也需要考虑等于sqrt的情况(比如4=2*2,4不是质数)

但是,我建议是使用i*i <=n作为判断条件,以避免浮点数精度运算和不必要的开根运算


//1可以是约数,但绝不是质数

届ける言葉を今は育ててる
最后更新于 2024-11-15