問題2改
ぎゃー、毎日更新するとか云っておきながら、さっそく三日坊主……。
いや、風邪が……。体調が………。
はい、すみません、四の五の云わずに問題2です。
前回: http://d.hatena.ne.jp/cocoatomo/20090419/1240148001
数学的考察
数列 の一般項は .
(式が煩雑になるので, 以下 と置く. 因みに, は黄金比. )
Fibonacci 数列を で見たときの周期は 3 で となっているので, 偶数の項は一般に, と書ける.
より であることに着目すると, を越えない偶数項のインデックスは以下の式を満たす.
これを満たす の中で最大のものを と置くと, 求める値は
ソースコード
上の考察をそのままコードにしたような, 誤差計算も好い加減なコード.
しかし, 意外とすんなり答えが出てビックリ. 数学の偉大さを改めて感じる. (まぁ, 俺が数学大好き, ってのがあるが.)
解法バージョンの切り替えには, そろそろ getopt でも使おうかな.
http://www.gnu.org/software/hello/manual/libc/Using-Getopt.html#Using-Getopt
#include <stdio.h> #include <stdlib.h> #include <math.h> long solveVer00(long); long solveVer01(long); int main(int argc, char **argv) { int version; long upperBound; upperBound = 4000000; if (argc == 1) { version = 0; } else if (argc == 2) { version = atoi(argv[1]); } else { version = atoi(argv[1]); upperBound = atol(argv[2]); } switch (version) { case 0: printf("Solution: %ld\n", solveVer00(upperBound)); break; case 1: printf("Solution: %ld\n", solveVer01(upperBound)); break; default: break; } return 0; } long solveVer00(long upperBound) { long firstTerm, secondTerm, temp, sum; sum = 0; firstTerm = 1; secondTerm = 2; while (secondTerm <= upperBound) { #if DEBUG printf("%ld, %ld\n", firstTerm, secondTerm); #endif if ((secondTerm % 2) == 0) { sum += secondTerm; } temp = firstTerm + secondTerm; firstTerm = secondTerm; secondTerm = temp; } return sum; } long solveVer01(long upperBound) { int maxIndex; double phi; // golden ratio phi = (1 + sqrt(5)) / 2; maxIndex = floor( log(sqrt(5) * upperBound + 1) / (3 * log(phi)) ); return floor( (pow(phi, 3 * (maxIndex + 1)) - 1) / (sqrt(5) * (pow(phi, 3) - 1)) ); }