题目:

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

思路:

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

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

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. ci url 控制 查询 通过路由 控制返回 视图的结果

    http://192.168.2.102/fastdatav/ChkUrl/daily/G8 http://192.168.2.102/fastdatav/ChkUrl/daily/ 放在 试图  控 ...

  2. linux下I2C驱动架构全面分析【转】

    本文转载自:http://blog.csdn.net/wangpengqi/article/details/17711165 I2C 概述 I2C是philips提出的外设总线. I2C只有两条线,一 ...

  3. tracert 路由跟踪程序

    C:\Users\Administrator>tracert 10.0.0.1 通过最多 30 个跃点跟踪到 10.0.0.1 的路由 1 <1 毫秒 1 ms 3 ms 192.168. ...

  4. [翻译]NUnit---Condition Asserts && Comparisons Asserts && Type Asserts (五)

    网址:http://www.cnblogs.com/kim01/archive/2013/03/31/2991597.html Condition Asserts 测试指定条件的方法称作条件测试,测试 ...

  5. [POI2011]LIZ-Lollipop

    https://www.zybuluo.com/ysner/note/1303462 题面 给一个只有\(1\)和\(2\)的序列,每次询问有没有一个子串的和为\(x\). \(n\leq10^6\) ...

  6. POJ1912 A highway and the seven dwarfs (判断凸包与直线相交 logn)

    POJ1912 给定n个点 和若干条直线,判断对于一条直线,是否存在两个点在直线的两侧. 显然原命题等价于 凸包与直线是否相交. O(n)的算法是显而易见的 但是直线数量太多 就会复杂到O(n^2)由 ...

  7. POJ2451 Uyuw's Concert (半平面交)

    POJ2451  给定N个半平面 求他们的交的面积. N<=20000 首先参考 POJ1279 多边形的核 其实就是这里要求的半平面交 但是POJ1279数据较小 O(n^2)的算法 看起来是 ...

  8. LR(逻辑回归)

    逻辑回归(Logistic regression): 想要理解LR,只需要记住: Sigmoid 函数: y=1/(1+e-z) 线性回归模型: y=wTx+b 最后: y= 1/(1+e-(wTx+ ...

  9. 清北考前刷题day7早安

  10. C#封装访问修饰符

    C# 封装 封装 被定义为"把一个或多个项目封闭在一个物理的或者逻辑的包中".在面向对象程序设计方法论中,封装是为了防止对实现细节的访问. 抽象和封装是面向对象程序设计的相关特性. ...