延伸:
如果是要寫出輸入n的位數,求出所有n位數的數字,
等同於其每一位的n次方的和的Armstrong數呢?
可以不要用到exp(), log()等函數嗎?
資料型別要注意什麼?
解:
運用之前個人的方式,
先將0~9的n次方存起來,
接著再將每個位數一次一次拆解以後取對應的n次方值加總。
用這個方法我們也可以算從1位到n位的Armstrong數。
只要運用迴圈,就可以有效的利用0~9的n次方值。
資料型別的部分,
由於C內建最長的型態應該是unsigned long long int,
其大小為2^64 - 1 = 18446744073709551615
而最長的Armstrong數為:
No.88 11513 22190 18763 99256 50955 97973 97152 2401
有36位,所以其實以內建的長度來說只能到20位。
但......跑到10位左右其實就已經會花很長的時間了,
我相信除了閒著沒事的人應該不需要它才是Orz......
使用long long int的話,printf的參數為%lld,
unsigned long long int的話應該是%llu。(若有錯請不吝指正)
下面Code分成只算單n位的,以及從1位數算到n位的Armstrong數。
單n位的Armstrong數:
int armstrong(int n) { unsigned long long int sum, num, i, ubnd=9, lbnd=1; int count, quoti, totalCnt = 0; unsigned long long int* uniE = (unsigned long long int*) malloc(sizeof(unsigned long long int)*10); for(count = 0; count <= 9; count++) uniE[count] = count; for(count = 2; count <= 9; count++) for(i = 2;i <= n; i++) uniE[count] *= count; for(i = 2; i <= n; i++) { lbnd *= 10; // lower_bound為1 00.....0 ubnd += 9*lbnd; // upper_bound為9 99.....9 } for(i = lbnd; i <= ubnd; i++) { num = i; sum = 0; while(num != 0) { quoti = num % 10; // 每次取個位數加入指數和 num /= 10; sum += uniE[quoti]; } if(sum == i) printf("%d: %llu\n", ++totalCnt, i); } free(uniE); uniE = 0; return totalCnt; }從1位算到n位的Armstrong數:
int armstrong(int n) { unsigned long long int sum, num, i, ubnd=9, lbnd=1; int count, quoti, digitCnt = 1, totalCnt = 0; unsigned long long int* uniE = (unsigned long long int*) malloc(sizeof(unsigned long long int)*10); uniE[0] = 0; for(count = 1; count <= 9; count++) { uniE[count] = count; printf("%2d: %d\n", ++totalCnt, count); // 1~9直接輸出 } while(++digitCnt <= n) { for(count = 2; count <= 9; count++) // 指數單位更新 uniE[count] *= count; lbnd *= 10; // lower_bound為1 00.....0 ubnd += 9*lbnd; // upper_bound為9 99.....9 for(i = lbnd; i <= ubnd; i++) { num = i; sum = 0; while(num != 0) { quoti = num % 10; // 每次取個位數加入指數和 num /= 10; sum += uniE[quoti]; } if(sum == i) printf("%d: %llu\n", ++totalCnt, i); } } free(uniE); uniE = 0; return totalCnt; }
沒有留言:
張貼留言