csu 1104 Fibonacci Numbers
2012-03-09 00:31
369 查看
超过8位只输出高低四位,中间用...隔开:
Fibonacci numbers get large pretty quickly, so whenever the answer has more than 8 digits, output only the first and last 4 digits of the answer, separating the two parts with an ellipsis (“...”).
高四位的输出:利用通项公式,先求出取对数的小数部分,然后取前四位即可。
第四位:直接递推会严重超时!!所以只能用矩阵幂的方法(其实题目提示了用线性代数知识:Use your linear algebra knowledge)
其实原来弄错了,以为是从第1项开始依次是0、1、1,中间还怀疑示例数据错了。。。o(╯□╰)o
所以在求后四位数那里,可以稍微改一下,返回时直接返回矩阵的某一个元素即可(f[0]=0,f[1]=1)
Fibonacci numbers get large pretty quickly, so whenever the answer has more than 8 digits, output only the first and last 4 digits of the answer, separating the two parts with an ellipsis (“...”).
高四位的输出:利用通项公式,先求出取对数的小数部分,然后取前四位即可。
第四位:直接递推会严重超时!!所以只能用矩阵幂的方法(其实题目提示了用线性代数知识:Use your linear algebra knowledge)
/* csu 1104 */ # include <stdio.h> # include <math.h> # include <time.h> # define MODN 10000 typedef struct Matrix { int a,b,c,d; } mat; int f[] = {0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597, 2584,4181,6765,10946,17711,28657,46368,75025,121393,196418, 317811,514229,832040,1346269,2178309,3524578,5702887,9227465, 14930352,24157817,39088169,63245986 }; mat cur, mpow, tmp; int last_4_dig(int n) { int i, k, m; m = (n-1)>>1; cur.a = cur.d = 1, cur.b = cur.c = 0; mpow.a = mpow.b = mpow.c = 1, mpow.d = 2; for (k = 31; k >= 0; --k) if ((m>>k) & 0x1) break; for (i = 0; i <= k; ++i) { if ((m>>i) & 0x1) { tmp = cur; cur.a = (tmp.a*mpow.a+tmp.b*mpow.c) % MODN; cur.b = (tmp.a*mpow.b+tmp.b*mpow.d) % MODN; cur.c = (tmp.c*mpow.a+tmp.d*mpow.c) % MODN; cur.d = (tmp.c*mpow.b+tmp.d*mpow.d) % MODN; } tmp = mpow; mpow.a = (tmp.a*tmp.a + tmp.b*tmp.c) % MODN; mpow.b = (tmp.b * (tmp.a+tmp.d)) % MODN; mpow.c = (tmp.c * (tmp.a+tmp.d)) % MODN; mpow.d = (tmp.c*tmp.b + tmp.d*tmp.d) % MODN; } if (n & 0x1) return (cur.a+cur.b)%MODN; else return (cur.c+cur.d)%MODN; } //int last_4_dig(int n) // 严重 TLE !! //{ // int a, b, i; // // i = 38; // a = f[38] % 10000; // b = f[39] % 10000; // // while (i+1 < n) // { // a = (a + b) % 10000; // b = (a + b) % 10000; // i += 2; // } // return (n&0x1) ? b:a; //} int main() { int n; double first_4_dig; freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); while (~scanf("%d", &n)) { if (n < 40) { printf("%d\n", f ); continue; } else { first_4_dig = n*log10(0.5*(1+sqrt(5)))-0.5*log10(5.0); first_4_dig -= (int)first_4_dig; first_4_dig = pow(10, first_4_dig); while (first_4_dig < 1000) first_4_dig *= 10; printf("%d", (int)first_4_dig); printf("...%04d\n", last_4_dig(n)); } } printf("time cost %.3lf\n", (double)clock()/CLOCKS_PER_SEC); return 0; }
其实原来弄错了,以为是从第1项开始依次是0、1、1,中间还怀疑示例数据错了。。。o(╯□╰)o
所以在求后四位数那里,可以稍微改一下,返回时直接返回矩阵的某一个元素即可(f[0]=0,f[1]=1)
相关文章推荐
- CSU 1104: 盒子游戏
- CSU1104-盒子游戏-博弈论
- CSU 1104 盒子游戏
- CSU 1104 盒子游戏(博弈)
- NY562 & CSU1104 盒子游戏【博弈】
- CSU-ACM2017暑期训练4-dfs F - Twenty-four point CSU - 1600
- CSU 1972:大梵天的恩赐(递推)
- CSU1565 Word Cloud
- CSU 1224: ACM小组的古怪象棋(BFS)
- CSU-ACM2017暑期训练6-bfs G - Mike and Shortcuts CodeForces - 689B
- CSU 1562 Fun House
- CSU-ACM2017暑假集训比赛2 CodeForces - 724D
- lightoj-1104-Birthday Paradox
- CSU-ACM2017暑期训练12-KMP F - 前缀后缀
- CSUOJ—1808
- CSU 1100一二三(水题)
- (CSU-1976)搬运工小明
- Interesting Calculator CSU - 1336
- csu1116(排列后prim)
- D - 复盘拉火车 CSU - 1898