• 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;
    }
    


     

  • 相关阅读:
    iOS之内存管理(ARC)
    分布式锁1 Java常用技术方案
    谈谈如何使用Netty开发实现高性能的RPC服务器
    前后端分离开发模式下后端质量的保证 —— 单元测试
    jquery实现"跳到底部","回到顶部"效果
    html内容超出了div的宽度如何换行让内容自动换行
    采用easyui+ajax+htm+ashx编写 通过用户对应角色 角色对应菜单 控制用户的访问权限
    javascript [] 与 {} 的区别
    图说设计模式
    T4教程1 T4模版引擎之基础入门
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3202949.html
Copyright © 2020-2023  润新知