题意:给定fibonacci数列,输入前缀,求出下标。题目中fibonacci数量达到100000,而题目输入的前缀顶多为40位数字,这说明我们只需要精确计算fibinacci数前40位即可。查询时使用字典树。在计算时,为了保证前40位精确无误。在此我计算了前60位。以保证前面不在进位。

注意点:

1)关于表示进位问题,需要控制计算的数位数在60以内,切记计算时不要错位(相同位要对齐)。

2)坑点:题目给出的数插入字典树最好插入前40位即可,否则MLE.

3)坑点:题目只要求计算下标不超过100000,计算到100000或者以上均会WA,因为输出值不是-1

下面是数组的AC代码:824ms

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<string>
#include<map>
#include<fstream>
#include<ctime>
#include<queue>
#include<vector>
#include<numeric>
#include<string.h>
#include<iomanip>
#include<sstream>
#include<algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef vector<int> BigInterger;
const int maxn = 100000;
const int maxsize = 10;
const int maxnum =65; struct TrieNode{
TrieNode(int d = -1) :id(d){ memset(next, NULL, sizeof(next)); }
int id;
TrieNode*next[maxsize];
};
TrieNode*T = new TrieNode; void insert(char*str,const int&index){
int len = strlen(str);
TrieNode*p = T;
int t = 0;
for (int i = len-1; i>=0&&t<40;i--,t++){
int id =str[i]-'0';
if (!p->next[id])p->next[id] = new TrieNode(index);
p = p->next[id];
}
} int search(char*str){
TrieNode*p = T;
while (*str != '\0'){
int id = *str++ - '0';
if (!p->next[id])return -1;
p = p->next[id];
}
return p->id;
}
void init(){
char f[3][maxnum];
f[1][0] ='1'; f[1][1] = '\0';
f[0][0] ='1'; f[0][1] = '\0';
insert("1", 0);
for (int i = 2; i<maxn; i++){
int g = 0,j=0,cnt = 0, x;
int r1 = (i - 1) % 3, r2 = (i - 2) % 3, r = i % 3;
int lena = strlen(f[r1]);
int lenb = strlen(f[r2]);
if (lena >= maxnum - 5){
memcpy(f[r1], f[r1]+1, lena - 1); f[r1][lena - 1] = '\0';
memcpy(f[r2], f[r2]+1, lenb - 1); f[r2][lenb - 1] = '\0';
lena--, lenb--;
}
while (g || j < lena||j<lenb){
x = g;
if (j < lena)x += f[r1][j]-'0';
if (j < lenb)x += f[r2][j]-'0';
f[r][cnt++] = x % 10+'0';
g = x / 10;
j++;
}
f[r][cnt] = '\0';
insert(f[r], i);
}
}
int main(){
init();
int T,kase=1;
char str[50];
scanf("%d", &T);
while(T--){
scanf("%s", str);
printf("Case #%d: %d\n",kase++,search(str));
}
return 0;
}

 采用向量AC的代码624ms(传值要用引用,否则多了不必要的复制):

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<string>
#include<map>
#include<fstream>
#include<ctime>
#include<queue>
#include<vector>
#include<numeric>
#include<string.h>
#include<iomanip>
#include<sstream>
#include<algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef vector<int> BigInterger;
const int maxn = 100000;
const int maxsize = 10;
const int maxnum =65; struct TrieNode{
TrieNode(int d = -1) :id(d){ memset(next, NULL, sizeof(next)); }
int id;
TrieNode*next[maxsize];
};
TrieNode*T = new TrieNode; void insert(const BigInterger&v,const int&index){
int len=v.size();
TrieNode*p = T;
int t = 0;
for (int i = len-1; i>=0&&t<40;i--,t++){
int id =v[i];
if (!p->next[id])p->next[id] = new TrieNode(index);
p = p->next[id];
}
} int search(char*str){
TrieNode*p = T;
while (*str != '\0'){
int id = *str++ - '0';
if (!p->next[id])return -1;
p = p->next[id];
}
return p->id;
}
//引用传值,避免赋值,效率更高
void add(BigInterger &a, BigInterger &b, BigInterger&c){
int lena = a.size(), lenb = b.size();
int g=0, x,i=0;
c.clear();
if (lena > maxnum - 5 || lenb > maxnum - 5){
a.erase(a.begin()), b.erase(b.begin());
lena--, lenb--;
}
while (g || i < lena || i < lenb){
x = g;
if (i < lena)x += a[i];
if (i < lenb)x += b[i];
c.push_back(x % 10);
g = x / 10;
i++;
}
}
void init(){
BigInterger a[3];
a[0].push_back(1);
a[1].push_back(1);
insert(a[1], 0);
for (int i = 2; i<maxn; i++){
add(a[(i - 1) % 3], a[(i - 2) % 3], a[i % 3]);
insert(a[i % 3], i);
}
}
int main(){
init();
int T,kase=1;
char str[50];
scanf("%d", &T);
while(T--){
scanf("%s", str);
printf("Case #%d: %d\n",kase++,search(str));
}
return 0;
}

  

 

hdu4099 Revenge of Fibonacci的更多相关文章

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

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

  2. hdu4099 Revenge of Fibonacci 字典树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4099 思想很容易想到 就是预处理出前10w个的fib数,然后建树查询 建树时只用前40位即可,所以在计 ...

  3. hdu 4099 Revenge of Fibonacci 大数+压位+trie

    最近手感有点差,所以做点水题来锻炼一下信心. 下周的南京区域赛估计就是我的退役赛了,bless all. Revenge of Fibonacci Time Limit: 10000/5000 MS ...

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

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

  5. [刷题]算法竞赛入门经典(第2版) 5-15/UVa12333 - Revenge of Fibonacci

    题意:在前100000个Fibonacci(以下简称F)数字里,能否在这100000个F里找出以某些数字作为开头的F.要求找出下标最小的.没找到输出-1. 代码:(Accepted,0.250s) / ...

  6. HDU 4099 Revenge of Fibonacci Trie+高精度

    Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: ...

  7. UVA 12333 Revenge of Fibonacci

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

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

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

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

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

随机推荐

  1. ajax是可以本地运行的

    ajax是可以本地运行的,经过验证,可以是可以,但跟浏览器有关,火狐和新IE可以,chrome不可以,旧ie不知道什么原因也不可以.但是浏览器也有它的安全策略,必须是同一目录下的文件可以访问.chro ...

  2. HDU - 2814 Visible Trees

    题意: m*n(1<=m,n<=100000)的森林里,起始点在(1,1),某人从(0,0)点开始看,问能看到多少棵树. 题解: 求出1~x中的每个数与1~y的数中互质的数的总和.用素数筛 ...

  3. codeforces school mark(贪心)

    ///太渣,看了题解才知道怎么做,自己想感觉想不清楚 ///题解:首先在给出的序列里判断小于median的个数,若大于(n-1)/2,则不满足,否则看另一个条件 ///这样我们可以把中位数左边还要添加 ...

  4. angular.extend(dst,src)的简单示例

    自我认为这个方法跟angular.copy(src,dst)有点相似.在angular.extend({},src)时,就可以画等号.这个src只代表一个对象.代码如下:(注意这个src可以有多个对象 ...

  5. 手动编写一个简单的loadrunner脚本

    loadrunner除了自动录制脚本外,还可以手动编写脚本,通过右键+inset step添加步骤,还可以手动添加事务,集合点等 下面是一个简单的Action脚本,服务是运行在本机的flask服务: ...

  6. OPENCV mat类

    OpenCV参考手册之Mat类详解 目标 我们有多种方法可以获得从现实世界的数字图像:数码相机.扫描仪.计算机体层摄影或磁共振成像就是其中的几种.在每种情况下我们(人类)看到了什么是图像.但是,转换图 ...

  7. noi2017 T1 整数 ——线段树

    loj.ac上有  题目传送门 不过我还是把题目搬过来吧 整数(integer)[题目背景]在人类智慧的山巅,有着一台字长为 1048576 位的超级计算机,著名理论计算机科 学家 P 博士正用它进行 ...

  8. 全自动google检索后台

    是不是每天为了找后台,伤破了蛋,每次在google输入”site:www.xxx.com intitle:登陆”.是不是手都累麻了,无聊又浪费时间.有了它,你的蛋就不用在碎了 直接上源码 1 2 3 ...

  9. 培训补坑(day5:最小生成树+负环判断+差分约束)

    补坑补坑((╯‵□′)╯︵┻━┻) 内容真的多... 一个一个来吧. 首先是最小生成树. 先讲一下生成树的定义 生成树就是在一张图上选取一些边,使得整个图上所有的点都连通. 那么我们要求的最小生成树有 ...

  10. MFC 获得各类指针、句柄的方法(转)

    原文转自 https://blog.csdn.net/abcjennifer/article/details/7480019 1.MFC中获取常见类句柄<视图类,文档类,框架类,应用程序类> ...