
题目:
Revenge of Fibonacci
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4099
分析:字典树的应用。在求Fibonacci的前40位时,可以只记录下前60位,舍去后面的,这样不会因为进位而产生误差。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string>
#include<algorithm>
#include<map>
#define maxn 6000005
using namespace std;
char s[],s1[],s2[],s3[];
char c[];
int ans=;
void padd(char *a,char *b,char *back)
{
int i,j,k,x,y,z,up;
i=strlen(a)-;
j=strlen(b)-;
k=;
up=;
while(i>=||j>=)
{
if(i<)x=;
else x=a[i]-'';
if(j<)y=;
else y=b[j]-'';
z=x+y+up;
c[k++]=z%+'';
up=z/;
i--;
j--;
}
if(up>)c[k++]=up+'';
for(i=;i<k;i++)back[i]=c[k--i];
back[k]='\0';
} struct Trie
{
Trie *next[];
int count;
};
Trie *root,memory[maxn];
int cnt=;
Trie* build()
{
Trie *p=&memory[cnt++];
p->count=-;
for(int i=;i<;i++)
p->next[i]=NULL;
return p;
}
void insert_node(char *s,int nn)
{
Trie *p=root;
int i,k;
for(i=;s[i]&&i<;i++)
{
k=s[i]-'';
if(p->next[k]==NULL)
p->next[k]=build();
p=p->next[k];
if(p->count==-)p->count=nn;
}
}
bool search(char *s)
{
Trie *p=root;
int i,k;
for(i=;s[i];i++)
{
k=s[i]-'';
if(p->next[k]==NULL)return false;
else p=p->next[k];
}
ans=p->count;
return true;
}
void init()
{
s1[]='';s1[]='\0';
s2[]='';s2[]='\0';
insert_node(s1,);
insert_node(s2,);
for(int i=;i<=;i++)
{
int len1=strlen(s1),len2=strlen(s2);
if(len2>)
{
s2[len2-]='\0';
s1[len1-]='\0';
}
padd(s1,s2,s3);
strcpy(s1,s2);
strcpy(s2,s3);
insert_node(s3,i);
}
}
int main()
{
int T,cas=;
root=build();
init();
scanf("%d",&T);
while(T--)
{
scanf("%s",s);
bool flag=search(s);
printf("Case #%d: ",cas++);
if(!flag)puts("-1");
else printf("%d\n",ans-);
}
return ;
}