哈理工1701 小胖子的Fibonacci 【字典树+大数加法】

  刚开始用了大数加法求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 }
原文地址:https://www.cnblogs.com/symons1992/p/3133825.html