UVA ~ 12333 ~ Revenge of Fibonacci (字典树 + 高精度)

题意:Fibonacci数的定义为: F(0)=F(1)=1,然后从F(2)开始,F(i)=F(i-1)+F(i-2)。例如,前10项Fibonacci 数分别为1,1,2,3,5,8,13,21,34,55...

有一天晚上,你梦到了Fibonacci,它告诉你一个有趣的Fibonacci 数。醒来以后,你只记得了它的开头几个数字。你的任务是找出以它开头的最小Fibonacci 数的序号。例如以12开头的最小Fibonacci 数是F(25)。

输入不超过40个数字,输出满足条件的序号。如果序号小于100000的Fibonacci 数均不满足条件,输出-1。

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

思路:高精度计算前100000个Fibonacci数,并将每个数字的前50个数存入字典树,然后查询就OK了。

我用原来自己写的大数模板一直超时,不知道为啥我的大数板子那么慢。。。只好手写个加法了

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5;
//Trie树
struct Trie
{
    int id;
    Trie *Next[10];
    Trie()
    {
        id = -1;
        for (int i = 0; i < 10; i++) Next[i] = NULL;
    }
};

void Insert(Trie* root, string s, int id)
{
    Trie* temp = root;
    for (int i = 0; i < s.size(); i++)
    {
        int index = s[i] - '0';
        if (temp->Next[index] == NULL)
        {
            temp->Next[index] = new Trie;
            temp->Next[index]->id = id;
        }
        temp = temp->Next[index];
    }
}

int Query(Trie* root, string s)
{
    Trie *temp = root;
    for (int i = 0; i < s.size(); i++)
    {
        int index = s[i] - '0';
        if (temp->Next[index] == NULL) return -1;
        temp = temp->Next[index];
    }
    return temp->id;
}

string add(string a, string b)
{
    int i = a.size()-1, j = b.size()-1, g = 0;
    string ans;
    while (i >= 0 || j >= 0 || g)
    {
        int x = g;
        if (i >= 0) x += (a[i] - '0');
        if (j >= 0) x += (b[j] - '0');
        g = x / 10;
        ans += (x%10 + '0');
        i--; j--;
    }
    reverse(ans.begin(), ans.end());
    return ans;
}
int main()
{
    Trie* root = new Trie;
    string a = "1", b = "1";
    Insert(root, "1", 0);
    Insert(root, "1", 1);
    for (int i = 2; i < MAXN; i++)
    {
        string sum = add(a, b);
        a = b; b = sum;
        if (sum.size() > 50) sum = sum.substr(0, 50);
        Insert(root, sum, i);
    }
    int T, CASE = 1; scanf("%d", &T);
    while (T--)
    {
        string str; cin >> str;
        int ans = Query(root, str);
        printf("Case #%d: %d\n", CASE++, ans);
    }
    return 0;
}
/*
15
1
12
123
1234
12345
9
98
987
9876
98765
89
32
51075176167176176176
347746739
5610
*/

猜你喜欢

转载自blog.csdn.net/zscdst/article/details/80144724
今日推荐