zoukankan      html  css  js  c++  java
  • hdu 4099 字典树 + 斐波那契

    题意:
          给你一个串(最长40位)问你这个串是斐波那契F(n)  n <= 99999中的那个数的前缀,如果存在多个输出最小的n否则输出-1.

    思路:
          给的串最长40位,那么就直接把所有的斐波那契全求出来(每个要前40位,求

    的时候多求几位,省着精度出问题,不能全求出来,存不下)求出来后把他们建在一颗字典树里面,建树的时候注意开一个变量记住当前位置的这个字母最早出现的是第几个斐波那契数,然后对于每组询问,直接查找就行了。


    #include<stdio.h>
    #include<string.h>
    #include<stdlib.h>
    
    typedef struct Tree
    {
        Tree *next[10];
        int v;
    }Tree;
    
    Tree root;
    
    void Buid_Tree(char *str ,int vv)
    {
        int len = strlen(str);
        Tree *p = &root ,*q;
        for(int i = 0 ;i < len ;i ++)
        {
            int id = str[i] - '0';
            if(p -> next[id] == NULL)
            {
                 q = (Tree *) malloc(sizeof(root));
                 q -> v = vv;
                 for(int j = 0 ;j < 10 ;j ++)
                 q -> next[j] = NULL;
                 p -> next[id] = q;
                 p = p -> next[id];
            }
            else p = p -> next[id];
         }
    }
    
    int Find(char *str)
    {
        int len = strlen(str);
        Tree *p = &root;
        for(int i = 0 ;i < len ;i ++)
        {
            int id = str[i] - '0';
            if(p -> next[id] == NULL) return -1;
            p = p -> next[id];
        }
         return p -> v;
    }
    
    void Buid()
    {
        int a[80] ,b[80] ,c[80];
        char str[60];
        for(int i = 0 ;i < 10 ;i ++)
        root.next[i] = NULL;
        str[0] = '1' ,str[1] = '';
        Buid_Tree(str ,0);
        memset(a ,0 ,sizeof(a));
        memset(b ,0 ,sizeof(b));
        memset(c ,0 ,sizeof(c));
        a[1] = b[1] = 1;
        for(int i = 2 ;i < 100000 ;i ++)
        {
            for(int j = 1 ;j <= 60 ;j ++)
            c[j] = a[j] + b[j];
            for(int j = 1 ;j <= 60 ;j ++)
            c[j+1] += c[j] / 10 ,c[j] %= 10;
            int max = 0;
            for(int j = 60 ;j >= 1 ;j --)
            if(c[j])
            {
              max = j; break;
            }
            int k = 0;
            for(int j = max ;j >= 1 ;j --)
            {
                str[k++] = c[j] + '0';
                if(k == 40) break;
            }
            str[k] = '';
            Buid_Tree(str ,i);
            if(max > 55)
            {
                for(int j = 6 ;j <= 60 ;j ++)
                b[j - 5] = b[j] ,c[j - 5] = c[j];
                for(int j = 56 ;j <= 60 ;j ++)
                b[j] = c[j] = 0;
            }
            for(int j = 1 ;j <= 60 ;j ++)
            {
               a[j] = b[j];
               b[j] = c[j];
               c[j] = 0;
            }
        }
    }
    
    int main ()
    {
        int t ,cas = 1;
        char str[50];
        Buid();
        scanf("%d" ,&t);
        while(t--)
        {
           scanf("%s" ,str);
           printf("Case #%d: %d
    " ,cas ++ ,Find(str));
        }
        return 0;
    }
    
    
     

  • 相关阅读:
    完全卸载Android Studio(卸载得干干净净)
    每日生活总结1
    求解协方差矩阵
    每天一个linux命令:ifconfig命令 临时修改重启后恢复原样
    每天一个linux命令(58):telnet命令
    每天一个linux命令:pwd命令
    每天一个linux命令(38):cal 命令
    每天一个linux命令:scp命令
    login shell与non-login shell的区别
    linux下重要的网络配置文件
  • 原文地址:https://www.cnblogs.com/csnd/p/12062981.html
Copyright © 2011-2022 走看看