hdu 4099 Revenge of Fibonacci 字典树+大数

将斐波那契的前100000个,每个的前40位都插入到字典树里(其他位数删掉),然后直接查询字典树就行。

此题坑点在于

1、字典树的深度不能太大,事实上,超过40在hdu就会MLE……

2、若大数加法时,保存的位数过少,就会导致低位误差,累积起来就可能导致前40位产生错误,解决办法是提高精度。



#include<iostream>
#include<cstring>
#include<string>
#include<cstdio>
using namespace std;

struct Trie
{
    struct Trie *son[10];
    int id;
}*root;
void insert(char s[],int ID)
{
    int i,j;
    struct Trie *c,*newnode;
    c=root;
    for(i=0;s[i];i++)
    {
        if(c->son[s[i]-'0'])
        {
            c=c->son[s[i]-'0'];
        }
        else
        {
            c->son[s[i]-'0']=new Trie;
            for(j=0;j<10;j++)    c->son[s[i]-'0']->son[j]=0;
            c=c->son[s[i]-'0'];
            c->id=ID;
        }
    }
}
int find(char *s)
{
    int i;
    int len;
    struct Trie *c;
    len=strlen(s);
    if(len==0)    return 0;
    c=root;
    for(i=0;i<len;i++)
    {
        if(c->son[s[i]-'0']!=0)
        {
            c=c->son[s[i]-'0'];
        }
        else
            return -1;
    }
    return c->id;
}
void init()
{
    root=new Trie;
    for(int i=0;i<10;i++)    root->son[i]=0;
}
char a[60]="1",b[60]="1",c[60];
int main()
{
    char str[50];
    int cas;
    int ca=1;
    init();
    insert("1",0);
    int la=1;
    int lb=1;
    for(int i=2;i<100000;i++)
    {
        int len=max(la,lb);
        int x=0;
        int top=0;
        for(int j=0;j<len;j++)
        {
            if(j>=la) a[j]='0';
            int s=x+a[j]+b[j]-2*'0';
            x=s/10;
            c[top++]=s%10+'0';
        }
        if(x) c[top++]=x+'0';
        c[top]='\0';
        if(top>50)              //计算数列的精度必须大一些
        {
            for(int j=0;j<49;j++) a[j]=b[j+1];a[la=49]='\0';
            for(int j=0;j<50;j++) b[j]=c[j+1];
            b[lb=50]='\0';
        }
        else
        {
            la=lb;
            strcpy(a,b);
            strcpy(b,c);
            lb=top;
        }
        int j,c;
        for(j=lb-1,c=0;j>=0&&c<40;c++,j--) str[c]=b[j];str[c]='\0';//字典树的深度绝对不能太大,超过40就要MLE!
        insert(str,i);
    }
  //  cout<<"ok"<<endl;
    cin>>cas;
    while(cas--)
    {
        scanf("%s",str);
        printf("Case #%d: %d\n",ca++,find(str));
    }
    return 0;
}


你可能感兴趣的:(hdu 4099 Revenge of Fibonacci 字典树+大数)