《C语言及程序设计》实践参考——完数

返回:贺老师课程教学链接  项目要求


【项目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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值