UVA - 12333 Revenge of Fibonacci 高精度加法 + 字典树
题目:给定一个长度为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 高精度加法 + 字典树的更多相关文章
- 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 ...
- UVa 12333 - Revenge of Fibonacci manweifc(模拟加法竖式 & 字典树)
题意: 给定n个(n<=40)数字, 求100000个以内有没有前面n个数字符合给定的数字的fibonacci项, 如果有, 给出最小的fibonacci项, 如果没有, 输出-1. 分析: 可 ...
- UVA 12333 Revenge of Fibonacci
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...
- UVa 12333 Revenge of Fibonacci (字典树+大数)
题意:给定一个长度小于40的序列,问你那是Fib数列的哪一项的前缀. 析:首先用大数把Fib数列的前100000-1项算出来,注意,一定不能是100000,要不然会WA的,然后每个数取前40位,不足4 ...
- HDU 4099 Revenge of Fibonacci(高精度+字典树)
题意:对给定前缀(长度不超过40),找到一个最小的n,使得Fibonacci(n)前缀与给定前缀相同,如果在[0,99999]内找不到解,输出-1. 思路:用高精度加法计算斐波那契数列,因为给定前缀长 ...
- UVA 11732 strcmp() Anyone? (压缩版字典树)
题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...
- HDU 4099 Revenge of Fibonacci (数学+字典数)
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4099 这个题目就是一个坑或. 题意:给你不超过40的一串数字,问你这串数字是Fibonacci多少的开头 ...
- fibonacci高精度加法
A Fibonacci sequence is calculated by adding the previous two members the sequence, with the first t ...
- UVA-12333 Revenge of Fibonacci(竖式加法模拟 & 字典树)
题目: 给出一个斐波那契数字的前缀,问第一个有这个前缀的数字在斐波那契数列中是第几个. 思路: 紫书提示:本题有一定效率要求.如果高精度代码比较慢,可能会超时. 利用滚动数组和竖式加法来模拟斐波那契相 ...
随机推荐
- WPF中Xaml编译正常而Designer Time时出错的解决办法
开发wpf时我们经常遇到一个xaml文件在设计时显示解析错误(比如在:VS或者Blend)而编译正常运行正常. 原因是:xaml的在Debug版本下必须为anyCPU. 解决办法: 1.打开工程文件x ...
- yum配置文件位置
centos的yum配置文件 cat /etc/yum.conf cachedir=/var/cache/yum //yum 缓存的目录,yum 在此存储下载的rpm 包和数据库,默认设置为/var/ ...
- chromedriver下载
https://www.cnblogs.com/vickey-wu/p/6629407.html
- unittest单元测试生成HTML测试报告
前言: HTMLTestRunner 是 Python 标准库的 unittest 模块的一个扩展,它可以生成 HTML的 测试报告. 一.下载HTMLTestRunnerNew.py文件: 下载链接 ...
- Java常见设计模式之观察者模式
在阎宏博士的<JAVA与模式>一书中开头是这样描述观察者(Observer)模式的: 观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式.模型-视图(Mo ...
- CRT Library Features
CRT Library Features The new home for Visual Studio documentation is Visual Studio 2017 Documentatio ...
- python 基础 列表 字符串转换
1. 字符串转列表 str1 = "hi hello world" print(str1.split(" "))输出:['hi', 'hello', 'worl ...
- Pycharm的远程代码编辑
作为一个从java转到python的程序猿,一直觉得python的远程代码调试能力不如java,远程调试一把需要各种改代码,牵扯到eventlet库的时候,问题就更严重,需要调整eventlet的各种 ...
- 转——AHRS(航姿参考系统)和IMU(惯性测量单元)的区别
AHRS(航姿参考系统)和IMU(惯性测量单元)的区别 [测试测量] 发布时间:2010-05-09 16:52:09 http://bbs.ednchina.com/BLOG_ARTICLE_1 ...
- Java核心技术 卷1 基础知识-第一天
基本数据类型 java是一种强数据类的的语言 共有8种基本数据类型 其中: 整型4种 int(4字节) short(2字节) long(8字节) byte(1字节) java中整型的范围与机器无关 长 ...