a905448839 发表于 2023-4-24 23:15:40

求1000之内的完数

问题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;
}

isdkz 发表于 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
页: [1]
查看完整版本: 求1000之内的完数