题意:给出某项斐波那契数的前几位,让输出最小的一项前缀为这个串的项数。
先高精度算出前100000项斐波那契的前50位。并把前40位存进字典树预处理一下。字典树节点值存为第几项。然后输入字符串直接查找。
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 50
int fib[3][N+1];
class trie
{
public:
trie* next[10];
int value;
trie()
{
for(int i=0; i<10; i++)
next[i]=0;
value=-1;
}
} root,*a;
void insert(trie* p,int* s,int n,int len)
{
p=&root;
int k=len;
while(k>=0&&len-k<=40)
{
if(!p->next[s[k]])
p->next[s[k]]=new trie;
p=p->next[s[k]];
if(p->value==-1)
p->value=n;
k--;
}
}
int find(trie* p,char* s)
{
p=&root;
int k=0,ans;
while(s[k]!='\0')
{
if(!p->next[s[k]-'0'])
return -1;
p=p->next[s[k]-'0'];
k++;
}
return p->value;
}
void init()
{
memset(fib,0,sizeof(fib));
char str[45];
fib[0][0]=1;
fib[1][0]=1;
insert(a,fib[0],0,0);
int i,j;
for(i=2; i<100000; i++)
{
int c=0;
for(j=0; j<=N; j++)
{
fib[2][j]=(c+fib[1][j]+fib[0][j])%10;
c=(c+fib[1][j]+fib[0][j])/10;
}
if(j==N+1&&c>0)
{
for(int t=0; t<N; t++)
{
fib[0][t]=fib[1][t+1];
fib[1][t]=fib[2][t+1];
}
fib[0][N]=0;
fib[1][N]=c;
}
else
{
for(int t=0; t<=N; t++)
{
fib[0][t]=fib[1][t];
fib[1][t]=fib[2][t];
}
}
int t;
for(t=N; t>=0; t--)
if(fib[1][t]) break;
insert(a,fib[1],i,t);
}
}
int main()
{
init();
char temp[45];
int t,ca=0;
scanf("%d",&t);
while(t--)
scanf("%s",temp),
printf("Case #%d: %d\n",++ca,find(a,temp));
return 0;
}