zoukankan      html  css  js  c++  java
  • csu 1104 Fibonacci Numbers

    超过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)

    /* 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[n]);
    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)

  • 相关阅读:
    Understanding about Baire Category Theorem
    Isometric embedding of metric space
    Convergence theorems for measurable functions
    Mindmap for "Principles of boundary element methods"
    Various formulations of Maxwell equations
    Existence and uniqueness theorems for variational problems
    Kernels and image sets for an operator and its dual
    [loj6498]农民
    [luogu3781]切树游戏
    [atAGC051B]Three Coins
  • 原文地址:https://www.cnblogs.com/JMDWQ/p/2386040.html
Copyright © 2011-2022 走看看