UVA-12333 Revenge of Fibonacci

Posted ISGuXing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA-12333 Revenge of Fibonacci相关的知识,希望对你有一定的参考价值。

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3755

题目大意:

意思不难理解,就是找到以某个字符串为前缀的最小的斐波拉契数列,并输出是第几个斐波拉契数。找不到就输出-1;

思路:大数加法,字典树。

ps:通过这道题接触到了大数加法。(虽然之前在刘汝佳的那本算法书里看到过阶乘的,但当时匆匆略过了)

该题是多组输入,我们就对斐波拉契数列预处理,将1——100000的斐波拉契数列找出来。

将它们存入字典树。长度超过40的就只压入长度为41的前缀。

然后在每个节点存入以当前前缀为最小的斐波拉契数的序号。

ps:斐波拉契数列不能多存了一个!只要你超过了100000个就wa,它卡了这个点;

之所以不全部存入是为了节省空间。不然会RE。

 

然后代码应该就能AC了。

ps:本人代码跑了8330ms,感觉都要tle了。看到他们都是几百ms就ac了,不造怎么写的。时间问题就没有去看。

 

代码如下

 1 #include<iostream>
 2 #include<stdio.h>
 3 using namespace std;
 4 string fib(string s1,string s2)
 5 {
 6     if(s1.length()<s2.length())
 7     {
 8         string temp=s1;
 9         s1=s2;
10         s2=temp;
11     }
12     int i,j;
13     for(i=s1.length()-1,j=s2.length()-1;i>=0;i--,j--)
14     {
15         s1[i]=char(s1[i]+(j>=0?s2[j]-0:0));
16         if(s1[i]-0>=10)
17         {
18             s1[i]=char((s1[i]-0)%10+0);
19             if(i) s1[i-1]++;
20             else s1=1+s1;
21         }
22     }
23     return s1;
24 }
25 string a[100002];
26 int cnt=1;
27 int sum[10000050][11];
28 int num[10000050];
29 void add(string s,int number)
30 {
31     int root=0;
32     for(int i=0;i<s.length()&&i<42;i++)
33     {
34         int xx=s[i]-0;
35         if(!sum[root][xx])
36         {
37             sum[root][xx]=cnt++;
38             num[sum[root][xx]]=number;//存入最小的前缀,因为数列本身就是从小到大排,存入序号就ok
39         }
40         root=sum[root][xx];
41     }
42 }
43 int Find(string s)
44 {
45     int root=0;
46     for(int i=0;i<s.length();i++)
47     {
48         int xx=s[i]-0;
49         root=sum[root][xx];
50         if(root==0)
51             return 0;
52     }
53     return num[root];
54 }
55 int main()
56 {
57     a[1]="1";
58     a[2]="1";
59     add(a[1],1);
60     add(a[2],2);
61     for(int i=3;i<=100000;i++)//预处理
62     {
63         a[i]=fib(a[i-1],a[i-2]);
64         add(a[i],i);
65     }
66     int T;
67     while(cin>>T)
68     {
69         int t=0;
70         string st;
71         while(T--)
72         {
73             t++;
74             cin>>st;
75             int tmp=Find(st);
76             if(tmp){
77                 cout<<"Case #"<<t<<": "<<tmp-1<<endl;//因为题目从0开始算,所以减一
78             }else{
79                 cout<<"Case #"<<t<<": "<<-1<<endl;
80             }
81         }
82     }
83     return 0;
84 }

 

以上是关于UVA-12333 Revenge of Fibonacci的主要内容,如果未能解决你的问题,请参考以下文章

UVA-12333 Revenge of Fibonacci(竖式加法模拟 & 字典树)

UVA 12333 大数,字典树

TOJ 3820 Revenge of Fibonacci(大数+trie)

hdu4099 Revenge of Fibonacci

hdu-5019 Revenge of GCD

HDU - 4995 - Revenge of kNN