练习:求完数问题

题目:

一个数如果恰好等于它的因子之和,这个数就称为"完数"。例如,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");
}

 

 

 

posted @ 2013-10-29 15:42  playerc  阅读(695)  评论(13编辑  收藏  举报
c4io.com Count Visitors
Web Counter