《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;
}
时间: 2024-10-25 02:47:51

《C语言及程序设计》实践参考——完数的相关文章

《C++语言基础》实践参考——有些数的阶乘不算了

返回:贺老师课程教学链接 项目要求 [项目2-有些数的阶乘不算了] 求n!的函数,当用户的输入为负数,以及输入数太大时(例如大于12),使用异常处理机制予以拒绝,并给出恰当的提示. [参考解答] #include <iostream> using namespace std; int fac(int n) { int result=1; if(n<0) throw string("Argument cannot be negative"); else if(n>

《C语言及程序设计》实践参考——三数最大值

返回:贺老师课程教学链接  C语言及程序设计初步  项目要求 [项目2-三数最大值]输入3个整数,输出其中的最大值.提示:求出两数的大值,再求这个大值与第三数间的大值,为三数最大值 [参考解答] #include <stdio.h> int main( ) { int a,b,c,max; printf("请输入3个整数:"); scanf("%d %d %d", &a, &b, &c); //先求出a和b的大值 if(a>

C++第10周项目4参考——完数

课程首页地址:http://blog.csdn.net/sxhelijian/article/details/7910565 [项目4:输出完数](课本p86第20题)一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完数.编程找出1000以内的所有完数.提示:首先从2到1000构造循环控制变量为i的外层循环.每次循环中,利用内嵌的循环逐个地求出i的因子,并累加起来(为提高效率,可能的因子从1到i/2),如果因子和等于i

《C语言及程序设计》实践参考——阿姆斯特朗数

返回:贺老师课程教学链接  项目要求 [项目5-阿姆斯特朗数]如果一个正整数等于其各个数字的立方和,则称该数为阿姆斯特朗数(亦称为自恋性数).如 407=4^3+0^3+7^3就是一个阿姆斯特朗数.试编程求1000以内的所有阿姆斯特朗数.[参考解答] #include <stdio.h> int main() { int i,m,k,n; for(n=1; n<=1000; ++n) { //计算n的各位数的立方和m k=n; m=0; while(k>0) { i=k%10; m

《C++语言基础》实践参考—— 链表类

返回:贺老师课程教学链接  项目要求 [项目 - 链表类]动态链表也是程序设计中的一种非常有用的数据结构.可以说,是否能够理解有关操作的原理,决定了你是否有资格称为"科班"出身.在后续的专业基础课中,相关的内容还会从不同的角度,反复地认识,反复地实践.不过,在现阶段多些体验,也是很有必要的了.(1)阅读下面的程序,回顾一下动态链表,阅读程序过程中,请用笔画一画形成链表的过程中指针值的变化. #include <iostream> using namespace std; s

《C++语言基础》实践参考——复数模板类

返回:贺老师课程教学链接 [项目6-复数模板类]    阅读教材例10.1.该例实现了一个复数类,但是美中不足的是,复数类的实部和虚部都固定只能是double型的.可以通过模板类的技术手段,设计Complex,使实部和虚部的类型为定义对象时指定的实际类型.    (1)要求类成员函数在类外定义.    (2)在此基础上,再实现减法.乘法和除法    你可以使用的main()函数如下. int main( ) { Complex<int> c1(3,4),c2(5,-10),c3; //实部和虚

《C++语言基础》实践参考——Josephus(约瑟夫环)问题

返回:贺老师课程教学链接  项目要求 [项目-Josephus(约瑟夫环)问题]n个小孩子围成一圈,从第一个小孩子开始顺时针方向数数字,到第m个小孩子离开,这样反反复复,最终只剩下一个小孩子,求第几个小孩子留下?    提示:约瑟夫环即是一个首尾相连的链表,在建立好这个环以后,从头结点开始,每次间隔m孩子删除一个结点,直至只余下一个结点(删除了n-1个).     参考下面的代码,也可以自行设计类. //链表结点kid,其中number为这个人的编号 struct kid { int numbe

《C++语言基础》实践参考——分数类中的运算符重载

返回:贺老师课程教学链接 [项目3-分数类中的运算符重载] (1)实现分数类中的运算符重载,在分数类中可以完成分数的加减乘除(运算后再化简).比较(6种关系)的运算.可以在第4周分数类代码的基础上开始工作. class CFraction { private: int nume; // 分子 int deno; // 分母 public: //构造函数及运算符重载的函数声明 }; //重载函数的实现及用于测试的main()函数 [参考解答] #include <iostream> #inclu

《C++语言基础》实践参考——小玩文件

返回:贺老师课程教学链接  项目要求 [项目1 - 小玩文件](1)下面程序的功能是统计文本文件abc.txt中的字符个数,请填空将程序补充完整. #include <iostream> #include <cstdlib> #include _____________ // (1) using namespace std; int main() { fstream file; file.open("abc.txt", _________); // (2) if