刚开始用了大数加法求10万个斐波那契数,但是后来发现我写的大数加法太慢了,就从网上找了个模板用了,然后还发现只要40位就行了,处理了一下,限制到45位(不知道为啥,这块写41,42,43,44都不行,写上45就行了),以后再研究。
再把字典树给改一下就行,还涉及到标号问题,这个从10万到1开始插入就可以解决题中要求的较小序号问题。
然后上代码,过程很艰难,不过也好终于过了。
1 #include <iostream> 2 #include <string> 3 #include <stdio.h> 4 #include <malloc.h> 5 #include <string.h> 6 using namespace std; 7 string fab[100000]; 8 struct node 9 { 10 int size; //该结点上的前缀单词的个数 11 int number; //该结点处的fib数字的序号 12 struct node *child[10]; //下一个单词的结点 13 }a; 14 typedef struct node NODE; 15 NODE *root; //表示根节点。(根节点里面什么也不包含) 16 string bigintadd(string a,string b) 17 { 18 int la,lb,lc,i,j,flag; 19 string c=""; 20 char t; 21 i=la=a.length()-1; 22 j=lb=b.length()-1; 23 flag=0; 24 while(i>=0&&j>=0) 25 { 26 t=a[i]+b[j]+flag-'0'; 27 if(t>'9') 28 { 29 t=t-10;flag=1; 30 } 31 else flag=0; 32 c+=t; 33 i--;j--; 34 } 35 while(i>=0) 36 { 37 t=a[i]+flag; 38 if(t>'9') 39 { 40 t=t-10;flag=1; 41 } 42 else flag=0; 43 c+=t; 44 i--; 45 } 46 while(j>=0) 47 { 48 t=b[j]+flag; 49 if(t>'9') 50 { 51 t=t-10;flag=1; 52 } 53 else flag=0; 54 c+=t; 55 j--; 56 } 57 if(flag) c+=(flag+'0'); 58 lc=c.length(); 59 for(i=0,j=lc-1;i<j;i++,j--) 60 { 61 t=c[i];c[i]=c[j];c[j]=t; 62 } 63 return c; 64 } 65 66 //void insert(char word[],int num) 67 void insert(string word,int num) 68 { 69 //int l=strlen(word); 70 int l=word.length(); 71 int i,j; 72 int temp; 73 NODE *s=root; 74 for(i=0;i<l;++i) 75 { 76 temp=word[i]-'0'; 77 if(s->child[temp]==NULL) //如果未出现,则建立一个。 78 { 79 NODE *t=(NODE *)malloc(sizeof(a)); 80 s->child[temp]=t; 81 t->size=1; 82 //if(i==l-1) t->number=num; 83 t->number=num; 84 for(j=0;j<10;++j) 85 { 86 t->child[j]=NULL; 87 88 } 89 s=t; //更换结点 90 } 91 else //如果出现了,则 92 { 93 s=s->child[temp]; 94 s->size++; 95 s->number=num; 96 } 97 } 98 return ; 99 } 100 //int check(char word[]) //字符串的查找 101 int check(string word) 102 { 103 //int l=strlen(word); //计算字符串的长度 104 int l=word.length(); 105 int i; 106 int temp; 107 int res; 108 NODE *p=root; 109 for(i=0;i<l;++i) 110 { 111 temp=word[i]-'0'; 112 if(p->child[temp]!=NULL) 113 { 114 p=p->child[temp]; 115 res=p->number; 116 } 117 else 118 { 119 return -1; 120 } 121 } 122 return res; 123 } 124 void init_tree() 125 { 126 int i; 127 root=(NODE *)malloc(sizeof(a)); 128 for(i=0;i<10;++i) 129 { 130 root->child[i]=NULL; 131 132 } 133 134 for(i=100000-1;i>=0;--i) 135 { 136 insert(fab[i],i); 137 } 138 139 return; 140 } 141 142 143 144 145 int main() 146 { 147 fab[0]="1"; 148 fab[1]="1"; 149 int la,lb,lr; 150 for (int i=2;i<100000;++i) 151 { 152 fab[i]=bigintadd(fab[i-1],fab[i-2]); 153 //找一种方法把长度限制在45左右 154 155 la=fab[i-1].length(); lb=fab[i-2].length(); lr=fab[i].length(); 156 if(lr>45) 157 { 158 fab[i-1].erase(la-1,1); 159 fab[i].erase(lr-1,1); 160 } 161 162 163 } 164 init_tree(); 165 //cout<<"finished"<<endl; 166 int t; 167 int i,j; 168 string test; 169 int l_test; 170 while(cin>>t) 171 { 172 while(t--) 173 { 174 cin>>test; 175 cout<<check(test)<<endl; 176 } 177 } 178 return 0; 179 }