您的位置:首页 > 其它

练习:求完数问题

2013-10-29 15:42 267 查看
题目:

一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如,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\n number:%d count:%d\n",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("\n");
}
}
/* 结束了。。。*/
printf("end\n");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: