题目:
一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如,6的因子为1、2、3,而6=1+2+3,因此6是“完数”。编程序找出1000之内的所有完数,并按下面格式输出其因子:
6 Its factors are 1 2 3
下面是我的代码,思想不多说,贪心算法。
//
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define DIVISERS_MAX_LENGTH (1024)
#define TOP (10000)
int main(void)
{
/*
* 储存因子,成对的储存。例如6
* 1,6, 2,3
*/
int divisers[DIVISERS_MAX_LENGTH] = {0};
int divisers_count = 0;
/* 要判断的数 */
int number;
int sum;
/* 指定 i的最大值, */
int i_max;
int i ;
int diviser;
for(number = 2; number < (TOP + 1) ; ++number ){
/* 所有数可以被 1 和 自己整除,所以,下面for 从 2 开始
sum = 1;
count = 2;
i = 2;
i_max = number /2
*/
divisers[0] = 1;
divisers[1] = number;
/* 关于 i < i_max .
因为整除啊,
m = i / n
如果 i 能被 n 整除,则,n 最小,m最大。
随着循环进行 最小和最大不断被求出来,所以超过最大的就不用再算了。
其实,这个地方使用 i < sqrt(number) +1 最好了。
*/
for (divisers_count = 2,i = 2,sum = 1,i_max = sqrt(number)+1; i < i_max; ++i){
if (!(number % i)){
if (!(divisers_count < DIVISERS_MAX_LENGTH)){
fprintf(stderr, "Too many divisers
number:%d count:%d
",number,divisers_count);
break;
}
divisers[divisers_count] = i;
diviser = number/i;
sum += i;
++ divisers_count;
if (diviser != i) {
divisers[divisers_count] = diviser;
sum += diviser;
++ divisers_count;
}
if (sum > number) break;
}
}
/* 下面是输出 */
if (sum == number){
printf("%d ,Its factors are : ", number);
for (i =0; i < divisers_count ; i += 2 ){
printf ("%d ",divisers[i]);
}
/*
这个因为是倒叙输出,数组可能不是偶数,所以要判断开始的位置
i的开始的位置应该是:
i = (count -1 )- ( -((count-1) -(i-2)) +1 )
化简后
i = 2*count -i -1;
*/
for (i = 2*divisers_count -i -1; i > 2; i-=2 ){
printf("%d ",divisers[i]);
}
printf("
");
}
}
/* 结束了。。。*/
printf("end
");
}