题目:给定一个长度为40的数字,问其是否在前100000项fibonacci数的前缀

因为是前缀,容易想到字典树,同时因为数字的长度只有40,所以我们只要把fib数的前40位加入字典树即可。这里主要讨论下怎么得到fib数的前40位。

首先,因为没可能每一项的fib都求出来的了。空间都存不下来。所以,只能够缩小规模,有个明显的道理,用每个fib的前60项相加取前40即可。为什么呢?因为没有后效性,后面的项相加不会影响到前40项。就是你有40--60这些项来缓冲就够了,这些才是主要的进位项。后面的相当于无穷小,影响不大。可以理解成误差把。。。两个浮点数差值不超过eps就相等,一样的意思。

所以,我们要做的是:

如果F1 和 F2 是大于40位数字的,那么我们就取前60位相加就好了,但是有一个很坑爹很坑爹的地方,就是:假如现在是取前3位吧,然后我取4位来消除误差(其实是不够的,我只是举例子)一个数字是123456,另一个是7894561,这样的话,大家都大于4位啊,但是位数不同啊,你没理由取1234+7894吧,这样就直接wa啊。123456 + 7894561 = 8018017.所以应该是取7894和123相加啊。

那么怎么知道那个是大那个是小啊,什么时候多一位什么时候位数没关系啊?,经测试,如果你一直取相同位数相加的话,会在284项时GG,不要问我怎么知道的,我找了一天的数据。

首先要知道的是,肯定是F2先到达60项的,因为F2绝对比F1大嘛。。所以,当F2到达61项的时候,我就要把F2的第61项砍掉,这个时候F2的项数变小了,同时,如果F1比F2少一位的,就是60位,会发生刚才那种坑爹的情况,所以这个时候也要把F1的第60位砍掉。不然就发生刚才的情况

那么如果都是61位呢?没事,F2都砍了,F1也砍。不然F1就比F2多啦。

所以是 if (lenstr2 > dd)  str1[lenstr1] = str2[lenstr2]='\0';//F2先到达,要砍同时砍   dd=60

注意不能分开判断

// if (lenstr1>dd) str1[lenstr1]='\0';
// if (lenstr2>dd) str2[lenstr2]='\0'; /gg的

为什么呢?很简单,因为F1=60(不大于dd),而F2=61(大于dd)砍掉了一位,这样就不行了,坑爹情况出现

然后说一下后效性,F1+F2 = F3,这个F3有61位怎么办?一样,循环,然后继续砍掉,,所以我一直保持了F2在60位(因为每次相加最多能增加一位,而增加后,我又砍掉了。不增加,我不砍就是了。),而F1,可能59位(坑爹情况),可能60位。

好累,这题想了好久。

抓住一点的就是,当他超过60位,要砍项,str[lenstr]='\0';把str[lenstr]这一项砍掉了。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn=1e6;
const int N=;//26个小写字母
struct node
{
//int flag;//标记以这个字母结尾为一个单词
int count;//标记以这个字母结尾为一个前缀
struct node *pNext[N];//26枚字符指针
} tree[maxn*N]; //大小通常设为 单词个数*单词长度
int t;//表明现在用到了那个节点
struct node *create ()
{
//需要新开一个字符节点,就是有abc这样,插入abd,则d需要新开节点
struct node *p=&tree[t++];
//p->flag=0; //初始值为0,不是整个单词
p->count=; //前缀是必须的,本身就是一个了
for (int i=; i<N; i++)
{
p->pNext[i]=NULL;//初始化指针
}
return p;
}
void insert (struct node **T,char str[],int cnt)
{
struct node *p = *T;
if (p==NULL)
{
p=*T=create();
}
// int lenstr = strlen
for (int i=; str[i] && i <= ; ++i)
{
int id = str[i]-'';
if (!p->pNext[id])
{
p->pNext[id]=create();
p->pNext[id]->count = cnt;
}
p = p->pNext[id];
}
if (!p->count) p->count = cnt;
}
int find (struct node *T,char str[])
{
if (T==NULL) return -;
struct node *p = T;
for (int i=; str[i]; ++i)
{
int id = str[i]-'';
if (!p->pNext[id]) return -;
p = p->pNext[id];
}
return p->count;
} int b[]= {}; //maxn关键,栈分配,系统帮你释放,要时间,不乱开
void bigadd (char str1[],char str2[],char str3[])
{
int len1=strlen(str1+);
int len2=strlen(str2+);
//int b[300]= {0}; //maxn关键,栈分配,系统帮你释放,要时间,不乱开
memset(b,,sizeof (b));
int i=len1;
int j=len2;
int h=;
while (i>=&&j>=)
{
b[h++]=str1[i--]-''+str2[j--]-'';
}
while (i>=)
{
b[h++]=str1[i--]-'';
}
while (j>=)
{
b[h++]=str2[j--]-'';
}
for (int i=; i<h; i++)
{
if (b[i]>=)
{
b[i+]++;
b[i]-=;
}
}
if (!b[h])
{
h--;
}
int t=h;
for (int i=; i<=h; i++)
{
str3[t--]=b[i]+'';
}
str3[h+]='\0'; //一定要手动结束
return ;
}
struct node *T = NULL;
char str1[],str2[],ans[];
void init ()
{
str1[]='';
str1[]='\0';
insert(&T,str1,);
str2[]='';
str2[]='\0';
insert(&T,str2,);
int lenstr1=,lenstr2=;
int dd=;
for (int i=; i<; ++i)
{
lenstr1 = strlen(str1+);
lenstr2 = strlen(str2+);
// if (lenstr1>=dd) str1[lenstr1]='\0';
// if (lenstr2>=dd) str2[lenstr2]='\0'; /gg的
if (lenstr2 > dd)
{
str1[lenstr1] = str2[lenstr2]='\0';//砍项
//str1[dd+1] = str2[dd+1] = '\0';
//考虑下为什么不行,因为一直都是60项了
}
// printf ("%s\n%s\n",str1+1,str2+1);
// lenstr1 = strlen(str1+1);
// lenstr2 = strlen(str2+1);
// printf ("%d %d\n",lenstr1,lenstr2);
bigadd(str1,str2,ans);
insert(&T,ans,i+);
strcpy(str1+,str2+);
strcpy(str2+,ans+);
//
// printf ("\n");
// printf ("%s [%d]\n",ans+1,i);
// printf ("\n");
} return ;
}
int gg;
void work ()
{
scanf("%s",str1+);
int t=find(T,str1); if (t!=-) --t;
printf ("Case #%d: %d\n",++gg,t);
return ;
}
int main()
{
#ifdef local
freopen("data.txt","r",stdin);
#endif
init();
int t;
scanf("%d",&t);
while (t--) work();
return ;
}

UVA - 12333 Revenge of Fibonacci 高精度加法 + 字典树的更多相关文章

  1. UVA - 12333 Revenge of Fibonacci (大数 字典树)

    The well-known Fibonacci sequence is defined as following: F(0) = F(1) = 1 F(n) = F(n − 1) + F(n − 2 ...

  2. UVa 12333 - Revenge of Fibonacci manweifc(模拟加法竖式 & 字典树)

    题意: 给定n个(n<=40)数字, 求100000个以内有没有前面n个数字符合给定的数字的fibonacci项, 如果有, 给出最小的fibonacci项, 如果没有, 输出-1. 分析: 可 ...

  3. UVA 12333 Revenge of Fibonacci

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

  4. UVa 12333 Revenge of Fibonacci (字典树+大数)

    题意:给定一个长度小于40的序列,问你那是Fib数列的哪一项的前缀. 析:首先用大数把Fib数列的前100000-1项算出来,注意,一定不能是100000,要不然会WA的,然后每个数取前40位,不足4 ...

  5. HDU 4099 Revenge of Fibonacci(高精度+字典树)

    题意:对给定前缀(长度不超过40),找到一个最小的n,使得Fibonacci(n)前缀与给定前缀相同,如果在[0,99999]内找不到解,输出-1. 思路:用高精度加法计算斐波那契数列,因为给定前缀长 ...

  6. UVA 11732 strcmp() Anyone? (压缩版字典树)

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

  7. HDU 4099 Revenge of Fibonacci (数学+字典数)

    传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4099 这个题目就是一个坑或. 题意:给你不超过40的一串数字,问你这串数字是Fibonacci多少的开头 ...

  8. fibonacci高精度加法

    A Fibonacci sequence is calculated by adding the previous two members the sequence, with the first t ...

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

    题目: 给出一个斐波那契数字的前缀,问第一个有这个前缀的数字在斐波那契数列中是第几个. 思路: 紫书提示:本题有一定效率要求.如果高精度代码比较慢,可能会超时. 利用滚动数组和竖式加法来模拟斐波那契相 ...

随机推荐

  1. 文件上传框的美化+预览+ajax

    1.文件上传基本写法: <input type="file" name="" id="" value="" /&g ...

  2. jquery.html5uploader.js 上传控件

    插件地址:http://blog.csdn.net/never_say_goodbye/article/details/8598521 先上个效果图: 相比来说,效果还是很不错的 使用MVC3做服务器 ...

  3. js刷新页面方法大全(转)

    刷新页面实现方式总结(HTML,ASP,JS) 转载  2008-11-13   作者:    我要评论 多种方法实现页面的刷新代码 定时刷新: 1,<script>setTimeout( ...

  4. 第三篇elasticsearch分布式安装

    elasticSearch 分布式安装 1.在elasticSearch下的config下elasticsearch.yml文件最后一行添加注意 一定要加空格在:后面cluster.name: wal ...

  5. std::min error C2059: 语法错误:“::” 的解决方法

    std::min error C2059: 语法错误:"::" 的解决方法 下面这段代码: size_t n = std::min(count_, num_elements); 编 ...

  6. Hibernate存储date/datetime问题,解决java的date与mysql的datetime不兼容

    主要原因是出在Hibernate的配置文件中. 症状 1. java文件类型java.util.Date,数据库类型datetime,Hibernate配置文件用date,存储进数据库的时间只有年月日 ...

  7. Coding 如何使用 Coding 开发 Coding

    Coding Anytime Anywhere Coding 团队有 70 多人,分布在全国各地(深圳,北京,上海,成都),我们使用 Coding 作为云端办公室,以云端协作的方式管理事务,文件等,我 ...

  8. web.config中authorization下的location中的path的设置 (转)

    项目下 有三个文件夹 A,B,C 验正方式是 Forms 验正 我要设置他们的访问权限为, A,匿名可访问 B,普通用户授权后才能访问 C,只允许管理员访问 <configuration> ...

  9. Linux6.7 安装图文

    Linux6.7 安装图文 选择第一个进行安装 1.  Install or upgrade an existing system   安装或升级系统 2.  Install system with ...

  10. Ajax.BeginForm 使用过程中遇到的问题

    一.Ajax.BeginForm设置的路由在浏览器中解析不到. 问题截图:在视图中设置"Counter/Index",在浏览器中显示的是"action='/'" ...