题目传送 : https://vjudge.net/problem/UVA-12333
大数+字典树
给几个斐波那契数的前缀,让你判断最小是第几个。。我写的大数怎么就过不了,只好用了小白的唉。。
边生成大数边插入,并且附加个id就行了。
注意说100000就开到100000别弄大,一大就错。
#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int AX = 1e5; //1e5,我1e5+5就wa了一次
char input[42];
int f[2][AX];
char F[AX];
int n;
typedef struct Trie_Node
{
int flag;
int id;
struct Trie_Node* next[10];
}TrieNode,*Trie;
TrieNode* Trie_createroot(){
TrieNode* root = new TrieNode();
memset(root->next,0,sizeof(root->next));
root->flag = 0;
return root;
}
void Trie_insert(Trie node,char* p,int id){
while(*p){
if(!node->next[*p-'0']){
node->next[*p-'0'] = Trie_createroot();
}
if(!node->id && !node->flag){
node->id = id;
}
node = node->next[*p-'0'];
p++;
}
if(!node->flag){
node->flag = 1;
node->id = id;
}
}
int Trie_search(Trie node,char* p){
while( *p ){
node = node->next[*p-'0'];
p++;
if(!node){
return -1;
}
}
return node->id;
}
int main(){
int T;
Trie root = Trie_createroot();
f[0][0] = f[1][0] = 1;
char o[3] = {'1'};
Trie_insert(root,o,0);
int s = 0,l = 1,p,q;
for(int i=2;i<AX;i++){
p = i%2; q= (i+1)%2;
for(int j=s;j<l;j++){
f[p][j] = f[p][j]+f[q][j];
}
for(int j=s;j<l;j++){
if(f[p][j]>=10){
f[p][j+1] += 1;
f[p][j] -= 10;
}
}
if(f[p][l]) l++;
if(l - s > 50) s++;
int count = 0,r=l-1;
while(r>=0 && count<=50){ //保存前50位
F[count++] = f[p][r--]+'0';
}
Trie_insert(root,F,i);
}
scanf("%d",&T);
int k = 0;
while(T--){
scanf("%s",input);
printf("Case #%d: ",++k);
printf("%d\n",Trie_search(root,input));
}
return 0;
}