zoukankan      html  css  js  c++  java
  • hdu 1568

    题目链接http://acm.hdu.edu.cn/showproblem.php?pid=1568

    我的天呐,写了那么久的代码,拼命地想省内存,可是还是没用呀,那么大一个数,数组至少就要那么大了呀,看看我那MLE的代码吧,原因是我用了递推公式,下面一个是直接用公式计算每一个的

    MLE的代码
    #include<iostream>
    #include
    <stdio.h>
    #include
    <math.h>
    #include
    <string.h>
    #include
    <stdlib.h>
    using namespace std;
    int sum[2][200];
    int len[2];
    int s[100000001];
    void init()
    {
    memset(sum,
    0,sizeof(sum));
    memset(len,
    0,sizeof(len));
    memset(s,
    0,sizeof(s));
    s[
    0]=0;
    sum[
    1][0]=1;len[2]=1;s[1]=1;
    sum[
    0][0]=1;len[1]=1;s[2]=1;
    int j,k;
    for(int i=3;i<100000001;i++)
    {
    for(j=0,k=0;j<len[(i-1)%2];j++)
    {
    k
    +=sum[i%2][j]+sum[(i+1)%2][j];
    sum[i
    %2][j]=k%100000000;
    k
    /=100000000;
    }
    while(k)
    {
    sum[i
    %2][j++]=k%100000000;
    k
    /=100000000;
    }
    len[i]
    =j;
    int p=j-1,ans;
    char str[10];
    s[i]
    =0;
    itoa(sum[i
    %2][p],str,10);
    int lj=strlen(str),m;
    for(m=0;m<lj;m++)
    {
    if(m>=4)break;
    s[i]
    =s[i]*10+str[m]-'0';
    }
    str[
    0]='\0';
    if(p>0&&m<4)
    {
    itoa(sum[i
    %2][p-1],str,10);
    lj
    =strlen(str);
    if(lj!=8) s[i]*=10,m++;
    for(int j=0;m<4;m++,j++)
    s[i]
    =s[i]*10+str[j]-'0';
    }
    }
    }
    int main()
    {
    int n;
    init();
    while(scanf("%d",&n)==1)
    {
    printf(
    "%d\n",s[n]);
    }
    return 0;
    }

    下面是来自大牛的http://hi.baidu.com/aekdycoin/blog/item/60bbae2b38c6f52ad42af18f.html

    先看对数的性质,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.....)

    取完对数

    log10(an)
    =-0.5*log10(5.0)+((double)n)*log(f)/log(10.0)+log10(1-((1-5)/(1+5))^n)其中f=(sqrt(5.0)+1.0)/2.0;
    log10(
    1-((1-5)/(1+5))^n)->0
    所以可以写成log10(an)
    =-0.5*log10(5.0)+((double)n)*log(f)/log(10.0);
    最后取其小数部分。

    #include
    <iostream>
    #include
    <cmath>
    using namespace std;
    int fac[21]={0,1,1};
    const double f=(sqrt(5.0)+1.0)/2.0;
    int main()
    {
       
    double bit;
       
    int n,i;
       
    for(i=3;i<=20;i++)fac[i]=fac[i-1]+fac[i-2];//求前20项
        while(cin>>n)
        {
           
    if(n<=20)
            {
                cout
    <<fac[n]<<endl;
               
    continue;
            }
            bit
    =-0.5*log(5.0)/log(10.0)+((double)n)*log(f)/log(10.0);//忽略最后一项无穷小
            bit=bit-floor(bit);
            bit
    =pow(10.0,bit);
           
    while(bit<1000)bit=bit*10.0;
            printf(
    "%d\n",(int)bit);
        }
       
    return 0;
    }

  • 相关阅读:
    将textarea滚动至底部:
    Web应用程序项目OxiteSite已配置为使用IIS.在本地计算机上找不到服务器
    使用Entity Framework时要注意的一些性能问题
    Python 输入输出
    Python 语言简介
    瞧一瞧,看一看,微信应用号(小程序)
    路遥眼里的河南人<平凡的世界>
    HTML5 本地存储实现购物车功能
    HTML5 本地存储的用法
    网站/域名如何备案?
  • 原文地址:https://www.cnblogs.com/nanke/p/2169013.html
Copyright © 2011-2022 走看看