zoukankan      html  css  js  c++  java
  • HDU1568_求fibonacci的前四位

    题目大意:

              求fibonacci数列的前面四位,注意f[0] = 0;

    解题思路:

              凡是要求数的前面几位的,都可以用两边求对数的思想。让我想起了,m = n^n.要求n的前面一位。这个时候用对数,

    lg(m) = n*lg(n), m = pow(10, n*lg(n)),之后求n*lg(n)的小数部分,因为整数部分为10^P(p代表整数),全都为10000……,而小数部分则为10^B(B代表小数部分),所以要取几位,就去小数那里取即可。

             这是网络上摘来的,写得very good:

            先看对数的性质,loga(b^c)=c*loga(b),loga(b*c)=loga(b)+loga(c);
            假设给出一个数10234432,那么log10(10234432)=log10(1.0234432*10^7)=log10(1.0234432)+7;
              log10(1.0234432)就是log10(10234432)的小数部分.
              log10(1.0234432)=0.010063744
             10^0.010063744=1.023443198
             那么要取几位就很明显了吧~
             先取对数(对10取),然后得到结果的小数部分bit,pow(10.0,bit)以后如果答案还是<1000那么就一直乘10。
             注意偶先处理了0~20项是为了方便处理~

         这题要利用到数列的公式:an=(1/√5) * [((1+√5)/2)^n-((1-√5)/2)^n](n=1,2,3.....)
    代码:

    #include<iostream>
    #include<cmath>
    const double N1 = (1.0 + sqrt(5.0)) / 2.0;
    const double N2 = (1.0 - sqrt(5.0)) / 2.0;
    using namespace std;
    int main(void)
    {
        int n;
        int f[21];
        f[0] = 0;
        f[1] = 1;
        f[2] = 1;
        for(int i = 3; i < 21; i++)
            f[i] = f[i-1] + f[i-2];
        while(scanf("%d", &n) == 1)
        {
            if(n <= 20)
            {
                printf("%d\n", f[n]);
                continue;
            }
            double temp1, temp2, ans;
            temp1 = log10(1.0 / sqrt(5.0));
            temp2 = (double)n * log10(N1) + log10(1.0 - pow(N2, (double)n));
            ans = temp1 + temp2;
            ans = ans - (int)ans;

            ans = pow((double)10, ans);
            // printf("%lf\n", ans);
            // printf("%lf\n", ans);
            printf("%d\n", (int)(ans * 1000));
        }
        return 0;
    }

    TLE代码:
    #include<iostream>
    using namespace std;
    const int MAX = 10005;
    char str[MAX], str1[MAX], str2[MAX];

    void add(char a[], char b[], char c[])
    {
        memset(c, '0', sizeof(c));
        int len1, len2, len;
        len1 = strlen(a);
        len2 = strlen(b);
        for(int i = len1 - 1, j = 0; i >= 0; i--, j++)
            c[j] = a[i];
        for(int i = len2 - 1, j = 0; i >= 0; i--, j++)
            c[j] += b[i] - '0';
        len = len1 >= len2 ? len1 : len2;

        for(int i = 0; i < len; i++)
        {
            if(c[i] > '9')
            {
                c[i] -= 10;
                c[i+1] ++;
            }
        }
        if(c[len] > '0')
            len++;
        c[len] = '\0';
        strrev(c);
        //for(int i = 0; i < len; i++)
        // printf("%c", c[i]);
        //printf("\n");
    }

    int main(void)
    {
        int n;
        int cas;

        /*strcpy(str1, "132424");
        strcpy(str2, "123424234");
        add(str1, str2, str);*/
        scanf("%d", &cas);
        while(cas--)
        {
            // scanf("%d", &n);

            for(int n = 1; n < 30; n++)
            {
                strcpy(str1, "1");
                strcpy(str2, "1");
                if(n == 1 || n == 2)
                {
                    printf("1\n");
                    continue;
                }
                for(int i = 3; i <= n; i++)
                {
                    memset(str, '0', sizeof(str));
                    add(str1, str2, str);
                    strcpy(str1, str2);
                    strcpy(str2, str);
                }
                printf("%s\n", str);
            }
        }
        return 0;
    }

  • 相关阅读:
    以相同类型的一个对象初始化另一个对象
    java之StringBuilder类详解
    java之StringBuffer类详解
    jquery在线引用地址
    java之抽象类
    Oracle动态执行表不可访问
    libvirt-qemu-TLS加密虚拟机传输实例分析
    查看系统是虚拟机还是物理机
    WorkStation 虚拟机迁移到 ESXi
    Django入门------常见问题
  • 原文地址:https://www.cnblogs.com/cchun/p/2620893.html
Copyright © 2011-2022 走看看