標題:黃金連分數 - 藍橋杯
內容:2013年第四屆藍橋杯全國軟件大賽預賽第4題。
作者:MilkCu
題目描述
標題: 黃金連分數
黃金分割數0.61803... 是個無理數,這個常數十分重要,在許多工程問題中會出現。有時需要把這個數字求得很精確。
對於某些精密工程,常數的精度很重要。也許你聽說過哈勃太空望遠鏡,它首次升空后就發現了一處人工加工錯誤,對那樣一個龐然大物,其實只是鏡面加工時有比頭發絲還細許多倍的一處錯誤而已,卻使它成了“近視眼”!!
言歸正傳,我們如何求得黃金分割數的盡可能精確的值呢?有許多方法。
比較簡單的一種是用連分數:
1
黃金數 = ---------------------
1
1 + -----------------
1
1 + -------------
1
1 + ---------
1 + ...
這個連分數計算的“層數”越多,它的值越接近黃金分割數。
請你利用這一特性,求出黃金分割數的足夠精確值,要求四舍五入到小數點后100位。
小數點后3位的值為:0.618
小數點后4位的值為:0.6180
小數點后5位的值為:0.61803
小數點后7位的值為:0.6180340
(注意尾部的0,不能忽略)
你的任務是:寫出精確到小數點后100位精度的黃金分割值。
注意:尾數的四舍五入! 尾數是0也要保留!
顯然答案是一個小數,其小數點后有100位數字,請通過瀏覽器直接提交該數字。
注意:不要提交解答過程,或其它輔助說明類的內容。
分析
按照題目給出的一種簡單方法,可以用斐波納契數列和模擬手算除法實現。
黃金分割數實際上是相鄰的兩個斐波那契數的商。
對於模擬手算除法,用下面代碼所示的for循環即可實現。
但是這種方法的精確度可能不夠。
代碼實現
# include <stdio.h> # define F 50 int main(void) { unsigned long long int fib[1000]; int f = 0; int a[101]; fib[0] = 0; fib[1] = 1; for(int i = 2; fib[i] < 1e18; i++) { fib[i] = fib[i - 1] + fib[i - 2]; f++; } printf("%d\n", f); unsigned long long int x = fib[F - 2]; unsigned long long int y = fib[F - 1]; for(int i = 0; i < 101; i++) { a[i] = x / y; x = (x % y) * 10; printf("%d", a[i]); } }
最后答案
0.6180339887498948481971959525508621220510663574518538453723187601229582821971784348083863296133320592
(全文完)