文章目录
完数的判断
题目描述
一个数如果恰好等于不包含它本身所有因子之和,这个数就称为"完数"。 例如,6的因子为1、2、3,而6=1+2+3,因此6是"完数"。 编程序找出N之内的所有完数,并按下面格式输出其因子
输入
N
输出
? its factors are ? ? ?
样例输出
6 its factors are 1 2 3
28 its factors are 1 2 4 7 14
496 its factors are 1 2 4 8 16 31 62 124 248
代码1:
#include<stdio.h>
#define max 1001
int main()
{
int n,i,j,a[max],l;
scanf("%d",&n);
for(i=1; i<=n; i++)
{
int tem=0,k=0; //每次开始新一轮的内循环之前重置
for(j=1; j<i; j++)
{
if(i%j==0) {//满足条件
tem+=j;//储存因子之和
a[k++]=j;//储存因子
}
}
if(tem==i)
{//满足条件 格式输出
printf("%d its factors are",i);
for(l=0;l<k;l++)
printf(" %d",a[l]);
printf("\n");
}
}
return 0;
}
思路:设置两层循环,外层循环遍历1到n,内层循环来判断它是不是完数。内层循环思路是找到各个因子,然后相加直接判断它是不是完数。
注意:每次结束内层循环都要把tem和k清零0
代码2(优化版):
#include <stdio.h>
int main()
{
int n;
scanf("%d", &n); //输入n
for (int i = 6; i <= n; i++) //for循环从第一个完数6开始
{
// if (i%10!=6 && i%10!=8) continue; //减少运行时间可加入此行,跳过个位非6与8的数
int s[100] = {0}; //初始化数组s全为0,循环内的临时数组每次循环都会初始化
int *p = s; //通过指针p的移动来控制数组的读写
for (int j = 1; j <= i / 2; j++)
{
if (i%j ==0)
{
*++p = j; //此处p先后移,再赋值储存因子j
s[0] += j; //s[0]储存因子的和
}
}
if (s[0] == i) //s[0]==i 则 i 为完数
{
printf("%d its factors are", i);
for (p = &s[1]; *p != 0; p++)//for循环p指向s[1],值为0时停止,每次循环后移一次
printf(" %d", *p);
putchar('\n');
}
}
return 0;
}
思路:这里的代码运行时间比上一版更短
优点一:它的遍历从6开始,缩短了数据的长度
优点二:这里使用了指针直接进行操作,速度更快
优点三:在内层循环时,它的代码区间为(1,i/2),这比上一种代码的(1,i)运行时间更短