hdu 4099 Revenge of Fibonacci(字典树)

Revenge of Fibonacci

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 204800/204800 K (Java/Others)

Total Submission(s): 2355    Accepted Submission(s): 587

Problem Description

The well-known Fibonacci sequence is defined as following:

Here we regard n as the index of the Fibonacci number F(n).

This sequence has been studied since the publication of Fibonacci‘s book Liber Abaci. So far, many properties of this sequence have been introduced.

You had been interested in this sequence, while after reading lots of papers about it. You think there’s no need to research in it anymore because of the lack of its unrevealed properties. Yesterday, you decided to study some other sequences like Lucas sequence
instead.

Fibonacci came into your dream last night. “Stupid human beings. Lots of important properties of Fibonacci sequence have not been studied by anyone, for example, from the Fibonacci number 347746739…”

You woke up and couldn’t remember the whole number except the first few digits Fibonacci told you. You decided to write a program to find this number out in order to continue your research on Fibonacci sequence.

Input

There are multiple test cases. The first line of input contains a single integer T denoting the number of test cases (T<=50000).

For each test case, there is a single line containing one non-empty string made up of at most 40 digits. And there won’t be any unnecessary leading zeroes.

Output

For each test case, output the smallest index of the smallest Fibonacci number whose decimal notation begins with the given digits. If no Fibonacci number with index smaller than 100000 satisfy that condition, output -1 instead
– you think what Fibonacci wants to told you beyonds your ability.

Sample Input

15
1
12
123
1234
12345
9
98
987
9876
98765
89
32
51075176167176176176
347746739
5610

Sample Output

Case #1: 0
Case #2: 25
Case #3: 226
Case #4: 1628
Case #5: 49516
Case #6: 15
Case #7: 15
Case #8: 15
Case #9: 43764
Case #10: 49750
Case #11: 10
Case #12: 51
Case #13: -1
Case #14: 1233
Case #15: 22374

题意:给你一个字符串,求最小的斐波那契数的下标,使这个字符串是这个斐波那契数的前缀。

题解:将0~99999斐波那契数存入字典树,只存前40位,在查找。

(注:加法只需保存前50位就可以保证精度了;第100000个斐波那契不能压入字典树,会wa;字典树只能压入40位数,不然会超内存)

#include<cstring>
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<string>
#include<algorithm>

#define N 100005

using namespace std;

int n;
char s[50],a[60],b[60],c[60];

struct Trie {
    int id;
    struct Trie *Next[10];
    Trie() {
        id=-1;
        for(int i=0; i<10; i++) {
            Next[i]=NULL;
        }
    }
};

Trie *p;

void Trie_Inser(Trie *p,char s[],int id) {
    int i=0;
    Trie *q=p;
    while(s[i]&&i<41) {
        int nx=s[i]-48;
        if(q->Next[nx]==NULL) {
            q->Next[nx]=new Trie;
        }
        q=q->Next[nx];
        if(q->id==-1) {
            q->id=id;
        }
        i++;
    }
}

void Add() {
    int la=strlen(a);
    int lb=strlen(b);
    int res[100];
    int l=0;
    la--,lb--;
    int t=0;
    while(la>=0) {
        res[l]=(a[la]-48)+(b[lb]-48)+t;
        t=0;
        if(res[l]>=10) {
            res[l]-=10;
            t=1;
        }
        la--;
        lb--;
        l++;
    }
    while(lb>=0) {
        res[l]=b[lb]-48+t;
        t=0;
        if(res[l]>=10) {
            res[l]-=10;
            t=1;
        }
        lb--,l++;
    }
    if(t) {
        res[l++]=1;
    }
    int i=0;
    int k=0;
    if(l>50) {
        k=l-50;
    }
    l--;
    while(l>=0&&i<50) {
        c[i++]=res[l--]+48;
    }
    c[i]='\0';
    lb=strlen(b);
    int lc=strlen(c);
    for(int j=0; j<lb-k; j++) {
        a[j]=b[j];
    }
    a[lb-k]='\0';
    for(int j=0; j<lc; j++) {
        b[j]=c[j];
    }
    b[lc]='\0';
}

void Init() {
    p=new Trie;
    a[0]='1',a[1]='\0';
    Trie_Inser(p,a,0);
    b[0]='1',b[1]='\0';
    for(int i=2; i<100000; i++) {
        Add();
        Trie_Inser(p,c,i);
    }
}

int Trie_Serch(Trie *p,char s[]) {
    int i=0;
    Trie *q=p;
    while(s[i]) {
        int nx=s[i]-48;
        if(q->Next[nx]==NULL)return -1;
        q=q->Next[nx];
        i++;
    }
    return q->id;
}

int main() {
    //freopen("test.in","r",stdin);
    Init();
    int t;
    cin>>t;
    int ca=1;
    while(t--) {
        scanf("%s",s);
        printf("Case #%d: %d\n",ca++,Trie_Serch(p,s));
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-03 11:25:31

hdu 4099 Revenge of Fibonacci(字典树)的相关文章

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

Revenge of Fibonacci 题意:给定fibonacci数列的前100000项的前n位(n<=40);问你这是fibonacci数列第几项的前缀?如若不在前100000项范围内,输出-1: 思路:直接使用数组模拟加法,再用Trie树插入查找即可:但是一般使用new Trie()的代码都是MLE的.反而我之前写的,直接得到数组大小的maxnode版本的内存可以接受:并且还有一点就是前40位的精度问题:由于是自己计算出来的finboncci数列,并不是系统给的,所以1的进位不会形成递推

hrbust 1209/hdu 4099 Revenge of Fibonacci【字典树+大数】

Revenge of Fibonacci Time Limit: 5000 MS Memory Limit: 204800 K Total Submit: 37(24 users) Total Accepted: 18(17 users) Rating:  Special Judge: No Description The well-known Fibonacci sequence is defined as following: F(0) = F(1) = 1 F(n) = F(n - 1)

HDU 4099 Revenge of Fibonacci

Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 204800/204800 K (Java/Others) Total Submission(s): 2027    Accepted Submission(s): 475 Problem Description The well-known Fibonacci sequence is defined as following: Here w

HDU 4099 Revenge of Fibonacci Trie+高精度

Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: Here we regard n as the index of the Fibonacci number F(n).  This sequence has been studied since the publication of Fibonacci's book Liber Abaci. So

hdu 1247 Hat’s Words 字典树

// hdu 1247 Hat's Words 字典树 // // 题目大意: // // 在一些字符串中,找到这样字符串:由两个其他的字符串构成 // // 解题思路: // // 字典树,先将这些字符串插入到字典树中,然后枚举断点,如果 // 字符串的前后两段都找到了,输出该串即可~ // // 感悟: // // 这道题目的话,就是字典树上的暴力嘛,细节方面还是要多多注意 // val值还是不能少哟~因为查找到了该串,不一定是一个单词,可能 // 是中间的一个节点,即某个字符串的前缀~~~

[ACM] hdu 1251 统计难题 (字典树)

统计难题 Problem Description Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀). Input 输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每一个提问都是一个字符串. 注意:本题仅仅有一组測试数据,处理到文件结束. Out

HDU 2094 产生冠军 (字典树+拓扑)

产生冠军 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 8591    Accepted Submission(s): 4047 Problem Description 有一群人,打乒乓球比赛,两两捉对撕杀,每两个人之间最多打一场比赛. 球赛的规则如下: 如果A打败了B,B又打败了C,而A与C之间没有进行过比赛,那么就认定,A一定能打

HDU 4287 Intelligent IME(字典树数组版)

Intelligent IME Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4776    Accepted Submission(s): 2227 Problem Description We all use cell phone today. And we must be familiar with the intelligen

hdu 4757 Tree(可持久化字典树)

题目链接:hdu 4757 Tree 题目大意:给定一棵树,每一个节点有一个值.如今有Q次询问,每次询问u到v路径上节点值与w亦或值的最大值. 解题思路:刚開始以为是树链剖分,事实上树链剖分仅仅是用来求LCA(能够不用树链剖分). 可持久化字典树.在每次插入的同一时候,不改动原先的节点.而是对全部改动的节点复制一个新的节点,而且在新的节点 上做操作,这样做的目的是可以获取某次改动前的状态.同过可持久化的操作,保留了改动前后的公共数据. 对给定树上的全部节点权值建立01字典树,然后每一个节点都保存