题目:

给出一个斐波那契数字的前缀,问第一个有这个前缀的数字在斐波那契数列中是第几个。

思路:

紫书提示:本题有一定效率要求。如果高精度代码比较慢,可能会超时。

利用滚动数组和竖式加法来模拟斐波那契相加的过程,在这个过程中每得出一个斐波那契数字就用字典树存一下。

PS:在滚动数组中存的斐波那契数字是逆序存储的。

代码:

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define MAX 1e9;
#define FRE() freopen("in.txt","r",stdin)
#define FRO() freopen("out.txt","w",stdout)
using namespace std;
typedef long long ll;
const int maxn = ;
struct Node {
int next[];
int id;
Node() {
for(int i = ; i<; i++) {
next[i] = -;
}
id = -;
}
};
Node trie[maxn];
int tot = ;
//Node root = trie[tot++]; int idx(char ch) {return ch-'';} void Insert(char* str, int id) {//字典树插入
// int u = 0;
// for(int i = 0; i<strlen(str); i++) {
// int v = idx(str[i]);//获取字符串当前位置的数字
// if(trie[u].next[v]==-1) { //如果这个位置是不存在的
// trie[u].next[v] = tot;
// u = tot++;
// } else { //如果这个位置是存在的
// u = trie[u].next[v];
// }
// if(trie[u].id==-1) {
// trie[u].id = id;
// }
// }
int u = ;
for(int i = ; i<strlen(str); i++){
int v = idx(str[i]);
if(trie[u].next[v]==-){//如果这个位置不存在
trie[u].next[v] = tot++;
}
u = trie[u].next[v];//结点往下走
if(trie[u].id==-){//保存这个斐波那契数字的id
trie[u].id = id;
}
}
} int Query(char* str) {
int u = ;
for(int i = ; i<strlen(str); i++) {
int v = idx(str[i]);
if(trie[u].next[v]==-) { //说明这个前缀不会出现
return -;
}
u = trie[u].next[v];
}
return trie[u].id;
} int fib[][maxn];
int main() {
FRE();
int s=,l=;
char f[];
Insert("",);
fib[][] = ;
fib[][] = ;
for(int i=; i<; i++) {
int a=i%, b=(i+)%;//滚动数组,可以手动跑两组斐波那契数字的相加就可以理解了
for(int k=s; k<l; k++) {
fib[a][k] = fib[a][k] + fib[b][k];
if(fib[a][k]>=) { //这位相加可以进位时
fib[a][k+]++;//下一位加一
fib[a][k] -= ;//这一位减掉进位的10
if(k==l-) { //最后一个进位让l加一
l++;
}
}
}
if(l-s>) { //数组中是倒着存这个数的,l-1表示个位开始,s表示最高位
s++;
}
int cnt=;
for(int k=l-; k>=s&&cnt<; k--){//根据题目提示,只选取前40位即可
f[cnt++] = fib[a][k]+'';
}
// if(i==10)
// printf("%s\n",f);
Insert(f,i);
memset(f,,sizeof(f));
}
//cout<<"GG"<<endl;
char str[];
int n;
scanf("%d",&n);
for(int i=; i<n; i++){
scanf("%s",str);
printf("Case #%d: ",i+);
int ans = Query(str);
printf("%d\n",ans==- ? -:ans-);
}
return ;
}

UVA-12333 Revenge of Fibonacci(竖式加法模拟 & 字典树)的更多相关文章

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

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

  2. UVA - 12333 Revenge of Fibonacci 高精度加法 + 字典树

    题目:给定一个长度为40的数字,问其是否在前100000项fibonacci数的前缀 因为是前缀,容易想到字典树,同时因为数字的长度只有40,所以我们只要把fib数的前40位加入字典树即可.这里主要讨 ...

  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 (大数 字典树)

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

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

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

  6. uva 10274 Fans and Gems(隐式图搜索+模拟)

    Fans and Gems Input: Standard Input Output: Standard Output Tomy's fond of a game called 'Fans and G ...

  7. N分之一 竖式除法模拟

    N分之一 Description Alice越来越痴迷于数学问题了.一天,爸爸出了个数学题想难倒她,让她求1 / n. 可怜的Alice只有一岁零九个月,回答不上来 ~~~~(>_<)~~ ...

  8. hdu 4099 Revenge of Fibonacci Trie树与模拟数位加法

    Revenge of Fibonacci 题意:给定fibonacci数列的前100000项的前n位(n<=40);问你这是fibonacci数列第几项的前缀?如若不在前100000项范围内,输 ...

  9. HDU4099 Revenge of Fibonacci(高精度+Trie)

    Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 204800/204800 K (Java/ ...

随机推荐

  1. selenium iframe 定位 qq空间说说

    selenium iframe 定位  qq空间说说

  2. linux 点命令

    cat a date . a Mon Jun :: CST linux .(点命令):读取并且在当前的shell中执行文件中的命令

  3. bzoj 4337 树的同构

    4337: BJOI2015 树的同构 Description 树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树 ...

  4. Java IO --ByteArrayOutputStream (六)***

    Java提供了很丰富的io接口,已经可以满足我们大部分读取数据的需求,这个在C读取数据需要自己定义缓冲区数组大小,而且要小心翼翼的防止缓冲区溢出的情况相当不同.一般情况下我们读取的数据都是直接读取成为 ...

  5. CodeForces 632C Grandma Laura and Apples (模拟)

    题意:有n个人买苹果,当苹果剩余偶数时买走一半,当苹果剩余奇数时,先买走一半,再用半价买走一个苹果,最终苹果恰好卖完.农民收入为多少. 析:反向模拟. 代码如下: #pragma comment(li ...

  6. 可视图linux--ubuntu的安装以及tool的安装

    1.下载ubuntu:http://cn.ubuntu.com/download/ 右键然后选择复制链接地址,然后将这个地址粘贴到迅雷,下载速度会比浏览器下载快. 2.创建虚拟机,安装ubuntu-- ...

  7. visual studio使用dos命令在生成项目时复制文件到指定目录

    本人使用软件:vs2015 拷贝“项目1”的 bin目录 下, 项目配置的名称(“Release”,“Debug”)目录下,所有内容到“项目2”输出目录(存在直接覆盖): xcopy $(Soluti ...

  8. unable to unroll loop 报错

    unable to unroll loop, loop does not appear to terminate in a timely manner (1024 iterations) 原本代码 f ...

  9. bzoj 1782: [Usaco2010 Feb]slowdown 慢慢游【dfs序+线段树】

    考虑每头牛到达之后的影响,u到达之后,从1到其子树内的点需要放慢的都多了一个,p为u子树内点的牛ans会加1 用线段树维护dfs序,每次修改子树区间,答案直接单点查询p即可 #include<i ...

  10. 引水入城 2010年NOIP全国联赛提高组(bfs+贪心)

    1066 引水入城 2010年NOIP全国联赛提高组  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description 在一个遥远 ...