鱼C论坛

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

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

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

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

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

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

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


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

  2. int main()
  3. {
  4.         int i,j,t;
  5.        
  6.         for(i = 2;i < 1000;i++)
  7.         {
  8.                 t = 0;
  9.                 for(j = 1;j <= i/2;j++)
  10.                 {
  11.                         if(i%j == 0)
  12.                         t += j;
  13.                 }
  14.                 //t += i;
  15.                 if(t == i)
  16.                 printf("%d ",i);        
  17.         }


  18.         return 0;
  19. }
复制代码

  1. #include <stdio.h>
  2. #include <math.h>

  3. int main()
  4. {
  5.     int i, j, t;

  6.     for (i = 2; i < 1000; i++)
  7.     {
  8.         t = 0;
  9.         for (j = 1; j <= sqrt(i); j++)//为什么可以只判断到i的平方根 可以推敲一下 以后!
  10.         {
  11.             if (i % j == 0)
  12.                 t += j;
  13.             if (j > 1 && i % (i / j) == 0 && i / j != j)
  14.                 t += (i / j);
  15.             
  16.         }
  17.         if (t == i)
  18.             printf("%d ", i);
  19.     }

  20.     return 0;
  21. }
复制代码

  1. #include <stdio.h>
  2. #include <math.h>

  3. int main()
  4. {
  5.     int i, j, t;

  6.     for (i = 2; i < 1000; i++)
  7.     {
  8.         t = 1; // 注意这里要把t初始化为1,因为1也是每个数的因子
  9.         for (j = 2; j <= sqrt(i); j++) // 注意这里从2开始循环
  10.         {
  11.             if (i % j == 0)
  12.             {
  13.                 t += j;
  14.                 if (i / j != j) // 如果i/j不等于j,则说明i/j也是i的因子
  15.                     t += i / j;
  16.             }
  17.         }
  18.         if (t == i)
  19.         printf("%d ", i);
  20.     }

  21.     return 0;
  22. }

复制代码
最佳答案
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
小甲鱼最新课程 -> https://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
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-10 09:53

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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