题目源自:PTA浙大版《C语言程序设计(第3版)》题目集
习题6-3 使用函数输出指定范围内的完数
裁判测试程序样例:
#include <stdio.h>
int factorsum( int number );
void PrintPN( int m, int n );
int main()
{
int m, n;
scanf("%d %d", &m, &n);
if ( factorsum(m) == m ) printf("%d is a perfect number\n", m);
if ( factorsum(n) == n ) printf("%d is a perfect number\n", n);
PrintPN(m, n);
return 0;
}
/* 你的代码将被嵌在这里 */
思路:
第一个函数寻找给定数字的因子,将因子进行累加即可。寻找因子的过程类似判断素数的过程,为了优化将其判断到 n u m b e r \sqrt number number或者 number/2
- 为什么要判断到number/2?
- 解释:以求n的因子为例。n除以
n
\sqrt n
n,得到
n
\sqrt n
n
如果n除以大于 n \sqrt n n的数,必得到小于 n \sqrt n n的商,而小于 n \sqrt n n的整数已经在2到 n \sqrt n n的整数试过了就没有必要再试了,商和除数互为n的因子,同理可以得到n/2。前者效率远高于后者,但由于题目未引入头文件#include<math.h>
所以就使用n/2。
第二个函数在给定区间进行遍历,输出。先判断是否为完数,如果是,再进行求每一个因子,在这里我使用数组进行储存,同样也可以不用数组存放直接输出即可。
注意点:
- 在进行第一个函数判断时,注意审题,除自身外的因子和,
1不是完数,1不是完数!!!!
提交多次发现总有一个点过不去,一直以为第二个函数出错了,重新考虑了一遍发现在第一个函数上有个坑。 - 在第二个函数上,不要忘记
样例2:区间内没有完数的情况
。 - 注意输出格式。
代码:
int factorsum( int number )
{
int sum=1;
for(int i=2;i<=number/2;i++){
if(number%i==0){
sum+=i;
}
}
//将为1的特殊情况排除
if(number==1){
return 0;
}else{
return sum;
}
}
void PrintPN( int m, int n )
{
int flag=0;//0表示区间内没有完数,1表示有
for(int i=m;i<=n;i++){
int a[10000];
int k=0;
if(factorsum(i)==i){
flag=1;
for(int j=2;j<=i/2;j++){
if(i%j==0){
a[k++]=j;
}
}
printf("%d = 1",i);//不要忘记1这个因子
for(int w=0;w<k;w++){
printf(" + %d",a[w]);
}
printf("\n");
}
}
if(flag==0){
printf("No perfect number");
}
}