題目:
一個數如果恰好等於它的因子之和,這個數就稱為"完數"。例如,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"); }