• HDU4099(斐波那契数列与字典树)


    题目:Revenge of Fibonacci

    题意:给出斐波那契数列的前k位,k不超过40,找出最小的正整数n,满足F(n)的前k位与给定数的前k位相同,斐波那契数列的项数不超过100000。

    解析:本题可以分为两步:

    第一步就是预处理出100000项斐波那契数列的前40位,插入到字典树中。

    第二步就是查询匹配求最小的n。

    对于第一步,我们可以把斐波那契数列精确到50多位,然后只存40位即可,这样就防止进位的误差。在斐波那契数列加法过程中,我们只把它的前50多

    位进行相加,不然存不下。

    #include <iostream>
    #include <string.h>
    #include <stdio.h>
    
    using namespace std;
    const int N=10;
    
    int f1[65],f2[65],f3[65];
    
    class Trie
    {
        public:
           int v;
           int flag;
           Trie *next[N];
           Trie()
           {
               v=-1;
               memset(next,NULL,sizeof(next));
           }
    };
    
    Trie *root;
    
    void Insert(char *S,int ans)
    {
        int len=strlen(S);
        Trie *p=root;
        for(int i=0;i<len;i++)
        {
            int id=S[i]-'0';
            if(p->next[id]==NULL)
                p->next[id]=new Trie();
            p=p->next[id];
            if(p->v<0) p->v=ans;
        }
    }
    
    int Find(char *S)
    {
        Trie *p=root;
        int count;
        int len=strlen(S);
        for(int i=0;i<len;i++)
        {
            int id=S[i]-'0';
            p=p->next[id];
            if(p==NULL) return -1;
            else  count=p->v;
        }
        return count;
    }
    
    void Init()
    {
        int h;
        char str[65]="1";
        memset(f1,0,sizeof(f1));
        memset(f2,0,sizeof(f2));
        memset(f3,0,sizeof(f3));
        f1[0]=1;f2[0]=1;
        Insert(str,0);
        for(int i=2;i<100000;i++)
        {
            memset(str,0,sizeof(str));
            int r=0;
            for(int j=0;j<60;j++)
            {
                f3[j]=f1[j]+f2[j]+r;
                r=f3[j]/10;
                f3[j]%=10;
            }
            for(int j=59;j>=0;j--)
            if(f3[j])
            {
                h=j;
                break;
            }
            int k=0;
            for(int j=h;j>=0;j--)
            {
                str[k++]=f3[j]+'0';
                if(k>=40) break;
            }
            Insert(str,i);
            if(h>55)
            {
                for(int j=1;j<59;j++)
                    f3[j-1]=f3[j];
                for(int j=1;j<59;j++)
                    f2[j-1]=f2[j];
            }
            for(int j=0;j<60;j++)
                f1[j]=f2[j];
            for(int j=0;j<60;j++)
                f2[j]=f3[j];
        }
    }
    
    int main()
    {
        root=new Trie();
        Init();
        char str[105];
        int t,i,j,k=1;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%s",str);
            printf("Case #%d: ",k++);
            int tmp=Find(str);
            printf("%d
    ",tmp);
        }
        return 0;
    }
    


     

  • 相关阅读:
    改变form里面input,textarea.select等的默认样式
    serialize() 方法
    纯css实现互动清单
    less学习笔记
    竖直手风琴导航菜单栏
    植树节快到了-那就种棵决策树吧
    简单写个logictic回归
    爬取纽约时报特定关键词新闻并计数
    (数学建模)非线性规划
    (CV学习笔记)看图说话(Image Captioning)-2
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3202949.html
Copyright © 2020-2023  润新知