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

 

原文地址:https://www.cnblogs.com/csnd/p/12062980.html