hdu 4099 Revenge of Fibonacci 字典树+斐波拉契数列数列
来源:互联网 发布:拍淘宝静物用什么相机 编辑:程序博客网 时间:2024/06/10 20:24
字典树应用
题意:给你N个数,让你找出是不是前100000个斐波拉契数列的前40位,如果是则输出下标最小的那个斐波拉契数列数列的下标。
思路:求斐波拉契数列数列的前100000项的前40位。我们只需要计算前55位的和就行了,因为我们只要前40位,计算55位便可以消除误差
这个也是最近才知道的结论,要保留前n位,那么我们就要计算n+m为,m一定大时,产生的进位误差将消失
如:133+267=390,267+390=657,390+657=1047,657+1047=1704 ,假如我们只要前2位,则,13+26=39,26+39=65,39+65=104,10+65=75,已经开始出错了。
如果,我们计算前n位,所以我们要计算n+m位,m一定大时,进位产生的误差将消失。
把计算好的斐波拉契数列数列的前40项存入到字典树中,并且把斐波拉契数列数列的下标也存入字典数中。因为下标是从小到大存入的,所以给出的N个查询的数,找到的
也是斐波拉契数列的最小的下标
详情见代码:
#include<stdio.h>#include<stdlib.h>#include<string.h>#include<algorithm>#include<iostream>#define maxn 5100001int cur=1;struct node{ int id; int next[12]; void init() { id=-1; memset(next,-1,sizeof(next)); }}trie[maxn];void Insert(char *s,int k){ //printf("%s\n",s); int p=0; int len=strlen(s); for(int i=0; i<len; i++) { int x=s[i]-'0'; if(trie[p].next[x]==-1) { trie[cur].init(); trie[p].next[x]=cur++; } p=trie[p].next[x]; if(trie[p].id==-1)trie[p].id=k;//当前下标为-1 才改变下标, //因为下标是从小到大依次存入到字典树中的 }}int Find(char *s,int len){ int p=0; for(int i=0; i<len; i++) { int x=s[i]-'0'; if(trie[p].next[x]==-1)return -1;//没有找到 p=trie[p].next[x]; } return trie[p].id;//找到返回下标}char a[70],b[70],c[70];void add()//计算斐波拉契数列数列的前100000项的前40位{ memset(a,'0',sizeof(a)); memset(b,'0',sizeof(b)); memset(c,'0',sizeof(c)); a[0]='1',a[1]='\0'; b[0]='1',b[1]='\0'; Insert(a,0); Insert(b,1); a[1]='0';b[1]='0'; int t=2,dc=0; while(t<100000) { for(int i=0; i<64; i++)//大数相加,计算前64位 { if(a[i]+b[i]+c[i]-'0'-'0'-'0'>9)//如果a+b,在加上当前位置的C要产生进位 c[i+1]+=1,c[i]+=a[i]+b[i]-'0'-'0'-10; else c[i]+=a[i]+b[i]-'0'-'0';//加上不产生进位 } dc=0; for(int i=63; i>=0; i--)//找到最高位 { if(c[i]>='1'&&c[i]<='9') { dc=i; break; } } if(dc>55)//保留55位 { for(int i=0; i<=65; i++) c[i]=c[i+1],b[i]=b[i+1]; dc--; } char dd[70]; int j=0; for(j=0; j<64; j++)//得到斐波拉契数列的前43位 { dd[j]=c[dc--]; if(dc==-1)break; if(j==43)break; } dd[j+1]='\0'; Insert(dd,t);//插入字典树 //if(t==50)break; strcpy(a,b); strcpy(b,c); memset(c,'0',sizeof(c)); t++; }}int main(){ trie[0].init(); add(); int t,ans=0; char str[45]; scanf("%d",&t); while(t--) { scanf("%s",str); int len=strlen(str); printf("Case #%d: %d\n",++ans,Find(str,len)); } return 0;}
0 0
- hdu 4099 Revenge of Fibonacci 字典树+斐波拉契数列数列
- hdu 4099 Revenge of Fibonacci 字典树+斐波拉契数列数列
- hdu 4099 Revenge of Fibonacci (字典树)
- hdu 4099 Revenge of Fibonacci(字典树)
- hdu 4099 Revenge of Fibonacci(字典树)
- hdu 4099 Revenge of Fibonacci 大数加法+字典树
- hdu 4099 Revenge of Fibonacci 字典树+大数
- HDU 4099 Revenge of Fibonacci(高精度+字典树)
- hdu 4099 Revenge of Fibonacci(字典树+大数加法)
- HDU 4099 Revenge of Fibonacci(高精度加法+字典树Trie)
- HDU 4099 Revenge of Fibonacci(大数加法+字典树)
- hrbust 1209/hdu 4099 Revenge of Fibonacci【字典树+大数】
- 字典树,数学(Revenge of Fibonacci,hdu 4099)
- HDU 4099 Revenge of Fibonacci(字典树+大数加法)
- HDU 4099 Revenge of Fibonacci (数学+字典数)
- HDU 4099 Revenge of Fibonacci
- hdu 4099 Revenge of Fibonacci
- HDU 4099 Revenge of Fibonacci
- nodejs:Excel导出json
- C++匿名命名空间
- CodeForces 342C Cupboard and Balloons
- eclipse最有用快捷键整理
- 【千里码】Task1-码之初
- hdu 4099 Revenge of Fibonacci 字典树+斐波拉契数列数列
- 1001
- Layer2-3 VLAN和DTP
- open函数的flag详解1
- org.json与json-lib的区别
- 简易抽屉实现
- Java关键字-strictfp
- Makefile 编写 简易教程 (实例)
- 勾股定理一日一证连载46