鱼C论坛

 找回密码
 立即注册
查看: 1175|回复: 1

[已解决]求1000之内的完数

[复制链接]
发表于 2023-4-24 23:15:40 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
问题1:以下三个代码都是正确的吗?
问题2:以下三个代码在for循环判断是不是完数的循环条件里 有些判断到那个数的平方根 有些判断那个数除以2  这两种方式判断的范围都是正确的吗?
问题3:如果问题2两种情况是正确的,举例 400的平方根是20 但是200也是他的因子 并不会被判断到平方根那个循环遍历到,虽然最终结果可能正确(400毕竟不是完数),但是逻辑是否正确呢?
假设400是一个完数 是不是应该要算上200这个因子去相加呢?那否则如何证明一个完数它最大的因子就是他的平方根呢?
问题4:以下第二个代码中如何理解呢?
        if (j > 1 && i % (i / j) == 0 && i / j != j)
                t += (i / j);

问题5:以下第三个代码中如何理解呢?
        if (i / j != j) // 如果i/j不等于j,则说明i/j也是i的因子
                   t += i / j; 

三代码如下:
#include<stdio.h>

int main()
{
        int i,j,t;
        
        for(i = 2;i < 1000;i++)
        {
                t = 0;
                for(j = 1;j <= i/2;j++)
                {
                        if(i%j == 0)
                        t += j; 
                }
                //t += i;
                if(t == i)
                printf("%d ",i);        
        } 


        return 0;
}
#include <stdio.h>
#include <math.h>

int main()
{
    int i, j, t;

    for (i = 2; i < 1000; i++)
    {
        t = 0;
        for (j = 1; j <= sqrt(i); j++)//为什么可以只判断到i的平方根 可以推敲一下 以后! 
        {
            if (i % j == 0)
                t += j;
            if (j > 1 && i % (i / j) == 0 && i / j != j)
                t += (i / j);
             
        }
        if (t == i)
            printf("%d ", i);
    }

    return 0;
}
#include <stdio.h>
#include <math.h>

int main()
{
    int i, j, t;

    for (i = 2; i < 1000; i++)
    {
        t = 1; // 注意这里要把t初始化为1,因为1也是每个数的因子
        for (j = 2; j <= sqrt(i); j++) // 注意这里从2开始循环
        {
            if (i % j == 0)
            {
                t += j;
                if (i / j != j) // 如果i/j不等于j,则说明i/j也是i的因子
                    t += i / j; 
            }
        }
        if (t == i)
        printf("%d ", i);
    }

    return 0;
}
最佳答案
2023-4-24 23:20:36
问题1:以下三个代码都是正确的吗?
答:是的,以下三个代码都可以找到1000以内的完数,但计算因子时采用了不同的策略。

问题2:以下三个代码在for循环判断是不是完数的循环条件里 有些判断到那个数的平方根 有些判断那个数除以2  这两种方式判断的范围都是正确的吗?
答:是的,这两种方式判断的范围都是正确的,但采用平方根的方式效率更高。因为当一个数的因子小于其平方根时,它必然有一个相对应的因子大于其平方根,所以只需检查到平方根就可以了。

问题3:如果问题2两种情况是正确的,举例 400的平方根是20 但是200也是他的因子 并不会被判断到平方根那个循环遍历到,虽然最终结果可能正确(400毕竟不是完数),但是逻辑是否正确呢?
假设400是一个完数 是不是应该要算上200这个因子去相加呢?那否则如何证明一个完数它最大的因子就是他的平方根呢?
答:逻辑是正确的。在采用平方根的循环条件时,会同时考虑相对应的大于平方根的因子。以400为例,在检查到20时,程序还会检查400除以20得到的商200,这样200作为因子也被计算在内了。关于完数的最大因子问题,实际上我们没有证明一个完数的最大因子就是其平方根。而是在判断一个数的因子时,只需要检查到平方根,因为在这个范围内的每一个因子都会有相对应的另一个因子。

问题4:以下第二个代码中如何理解呢?
        if (j > 1 && i % (i / j) == 0 && i / j != j)
                t += (i / j);
答:这行代码在检查因子j时,同时检查其相对应的因子 i/j。为了避免重复计算平方根情况下的因子,当j等于1时,i/j等于i,此时不会加入因子和,因此需要 j > 1。同时需要保证 i / j != j,避免重复计算同一个因子。

问题5:以下第三个代码中如何理解呢?
        if (i / j != j) // 如果i/j不等于j,则说明i/j也是i的因子
                   t += i / j;
答:这行代码同样在检查因子j时,同时检查其相对应的因子 i/j。当i
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-24 23:20:36 | 显示全部楼层    本楼为最佳答案   
问题1:以下三个代码都是正确的吗?
答:是的,以下三个代码都可以找到1000以内的完数,但计算因子时采用了不同的策略。

问题2:以下三个代码在for循环判断是不是完数的循环条件里 有些判断到那个数的平方根 有些判断那个数除以2  这两种方式判断的范围都是正确的吗?
答:是的,这两种方式判断的范围都是正确的,但采用平方根的方式效率更高。因为当一个数的因子小于其平方根时,它必然有一个相对应的因子大于其平方根,所以只需检查到平方根就可以了。

问题3:如果问题2两种情况是正确的,举例 400的平方根是20 但是200也是他的因子 并不会被判断到平方根那个循环遍历到,虽然最终结果可能正确(400毕竟不是完数),但是逻辑是否正确呢?
假设400是一个完数 是不是应该要算上200这个因子去相加呢?那否则如何证明一个完数它最大的因子就是他的平方根呢?
答:逻辑是正确的。在采用平方根的循环条件时,会同时考虑相对应的大于平方根的因子。以400为例,在检查到20时,程序还会检查400除以20得到的商200,这样200作为因子也被计算在内了。关于完数的最大因子问题,实际上我们没有证明一个完数的最大因子就是其平方根。而是在判断一个数的因子时,只需要检查到平方根,因为在这个范围内的每一个因子都会有相对应的另一个因子。

问题4:以下第二个代码中如何理解呢?
        if (j > 1 && i % (i / j) == 0 && i / j != j)
                t += (i / j);
答:这行代码在检查因子j时,同时检查其相对应的因子 i/j。为了避免重复计算平方根情况下的因子,当j等于1时,i/j等于i,此时不会加入因子和,因此需要 j > 1。同时需要保证 i / j != j,避免重复计算同一个因子。

问题5:以下第三个代码中如何理解呢?
        if (i / j != j) // 如果i/j不等于j,则说明i/j也是i的因子
                   t += i / j;
答:这行代码同样在检查因子j时,同时检查其相对应的因子 i/j。当i
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-12-24 20:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表