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