hdu 4099 Revenge of Fibonacci (字典树)

来源:互联网 发布:反马赛克软件 编辑:程序博客网 时间:2024/05/04 14:06

题目大意:

问前缀为给出的 串的斐波那契数列的最小下标,斐波那契最多给出前40个。


思路:
我们保存斐波那契的前50 个。

然后在高精度加的时候损失的精度也不会影响结果。

然后插入的时候只插入前40个  多了就不插



#include <cstdio>#include <iostream>#include <algorithm>#include <cstring>using namespace std;struct foo{    int save[51];    void init()    {        memset(save,0,sizeof save);    }    int get()    {        int pos=50;        while(save[pos]==0)pos--;        return pos;    }}s[3];foo add(foo a,foo b){    foo res;    res.init();    for(int i=0;i<50;i++)    {        res.save[i]=a.save[i]+b.save[i]+res.save[i];        if(res.save[i]>=10)        {            res.save[i]%=10;            res.save[i+1]++;        }    }    return res;}struct node{    struct node *br[10];    int num;};node *root;void Trie_init(){    root=new node;    root->num=0;    for(int i=0;i<10;i++)root->br[i]=NULL;}void Trie_insert(foo str,int pos,int mak){    node *s=root;    int i,ct;    for(i=pos,ct=0;i>=0 && ct<41;i--,ct++)//ct<=41 MLT 出翔  就卡的这么好  你敢信?    {        int id=str.save[i];        if(s->br[id]==NULL)        {            node *t=new node;            for(int j=0;j<10;j++)t->br[j]=NULL;            t->num=mak;            s->br[id]=t;            s=s->br[id];        }        else {            s=s->br[id];        }    }}int Trie_find(char str[]){    int len=strlen(str);    node *s;    s=root;    int res;    for(int i=0;i<len;i++)    {        int id=str[i]-'0';        if(s->br[id]==NULL)return -1;        else        {            s=s->br[id];            res=s->num;            //printf("%d ",res);        }    }    return res;}void Trie_del(node *p){    for(int i=0;i<10;i++)    {        if(p->br[i]!=NULL)          Trie_del(p->br[i]);    }    free(p);}void move(foo &t){    int pos=t.get();    for(int i=1;i<=pos;i++)    {        t.save[i-1]=t.save[i];    }    t.save[pos]=0;}int main(){    Trie_init();    s[0].init();    s[1].init();    s[0].save[0]=1;    s[1].save[0]=1;    Trie_insert(s[0],0,1);    //cout<<"---"<<endl;    for(int i=3;i<=100000;i++)    {        s[2].init();        s[2]=add(s[0],s[1]);        if(s[2].save[50])        {            move(s[2]);            move(s[1]);        }        int pos=s[2].get();       // s[i].print();        Trie_insert(s[2],pos,i);        s[0]=s[1];        s[1]=s[2];    }    int n;    char str[50];    int CASE=1;    while(scanf("%d",&n)!=EOF)    {        for(int cas=1;cas<=n;cas++)        {            scanf("%s",str);            int ans=Trie_find(str);            printf("Case #%d: %d\n",cas,ans!=-1?ans-1:ans);        }    }    Trie_del(root);    return 0;}


0 0
原创粉丝点击