【项目1-完数】
一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完数。
(1)输入一个数n,判断n是否是完数
[参考解答]
解1:
#include <stdio.h> int main( ) { int n,s,m; printf("输入n:"); scanf("%d", &n); s=1; //s代表因子和。1是任何数的因子,所以初值s=1,要判断m是否是n的因子,m的取值范围为2到m-1 for(m=2; m<n; m++) { if(n%m==0) s+=m; } if(n==s) { printf("Yes\n"); //额外增加一个功能,列出这些因子 printf("完数构成: %d = 1 ", n); for(m=2; m<n; m++) { if(n%m==0) printf("+ %d ", m); } } else { printf("No"); } printf("\n"); return 0; }
解2(改进版——提高效率)
#include <stdio.h> #include <math.h> int main( ) { int n,s,m; printf("输入n:"); scanf("%d", &n); s=1; //下面的循环次数较解法1少了很多(n越大,效果越明显),充分利用了因子的对称性 for(m=2; m<sqrt(n); m++) //思考:若s初值为1,m从1开始,结果会怎样? { if(n%m==0) //若m是n的因子,则n/m也是n的因子,一旦判断m是n的因子,一次将两个数都累加起来 s+=(m+n/m); //例:n=56时,判断出56%2==0为真,则将2及与其对应的因子28一次累加到s上,m到7即可结束循环 } if(m*m==n) //若恰好n是某数的平方,上面的循环中没有考虑,现在补上。当然,m只能被累加一次 s+=m; //printf("因子和:%d", s); //测试时可以加上这一句看看 if(n==s) { printf("Yes\n"); } else { printf("No"); } printf("\n"); return 0; }
(2)输出1000以内的所有完数
[参考解答]
有了上面的工作,很容易做一个双重循环,解决这个问题。
#include <stdio.h> #include <math.h> int main( ) { int n,s,m; printf("1000之间的完数有:"); for(n=2; n<=1000; ++n) { s=1; for(m=2; m<sqrt(n); m++) { if(n%m==0) s+=(m+n/m); } if(m*m==n) s+=m; if(n==s) printf("%d ", n); } printf("\n"); return 0; }
(3)亲密数:如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。求3000以内的全部亲密数。(提示:按照亲密数定义,要判断数a是否有亲密数,只要计算出a的全部因子的累加和为b,再计算b的全部因子的累加和为n,若n等于a则可判定a和b是亲密数。)
[参考解答]
#include <stdio.h> int main() { int i,a,b,n; for(a=1;a<=3000;++a) { //计算a的所有因子的和b b=0; for(i=1;i<a;++i) { if(a%i==0) b+=i; } //计算b的所有因子的和n n=0; for(i=1; i<b; ++i) { if(b%i==0) n+=i; } if(a==n) //a与其因子和的因子和相等 { printf("a= %d, 其因子和b=%d\n", a, b); } } printf("\n"); return 0; }
时间: 2024-10-25 02:47:51