算法竞赛入门经典 第二版 习题5-15 Fibonacci的复仇 Revenge of Fibonacci uva12333

题目:https://vjudge.net/problem/UVA-12333

思路: 大整数类+字典树
一开始套刘汝佳大整数类的板子套出好多问题,之后自己用string重新封装了一个。
用大整数类求出斐波那契数列然后将前42位插入字典树,便于之后查找前缀。

这题做出了灵异事件,在自己机器上预处理好几分钟都跑不完结果交上去竟然AC了。。。。。

代码:c++

#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 100000;
const int INF = 2147483647;

struct BigInteger
{
    string s;
    BigInteger(long long num = 0)
    {
        if (num == 0)
        {
            s.push_back(0);
        }
        else
        {
            while (num > 0)
            {
                s.push_back(num % 10);
                num /= 10;
            }
        }
    }
    BigInteger(const BigInteger &t)
    {
        s = t.s;
    }
    void operator = (const BigInteger &t)
    {
        s = t.s;
    }
    string tostring()
    {
        string ans;
        for (int i = s.size() - 1; i >= 0; i--)
        {
            ans.push_back(s[i] + '0');
            if (ans.size() >= 45)
            {
                break;
            }
        }
        return ans;
    }
    BigInteger operator + (const BigInteger &t)
    {
        BigInteger ans;
        ans.s.clear();
        int i = 0;
        bool carry_over = false;//进位标志
        const string &minn = s.size() < t.s.size() ? s : t.s;
        const string &maxx = t.s.size() > s.size() ? t.s : s;
        for (; i < minn.size(); i++)
        {
            int a = minn[i] + maxx[i] + carry_over;
            if (a >= 10)
            {
                a %= 10;
                carry_over = true;
            }
            else
            {
                carry_over = false;
            }
            ans.s.push_back((char)a);
        }
        for (; i < maxx.size(); i++)
        {
            int a = maxx[i] + carry_over;
            if (a >= 10)
            {
                a %= 10;
                carry_over = true;
            }
            else
            {
                carry_over = false;
            }
            ans.s.push_back((char)a);
        }
        if (carry_over)
        {
            ans.s.push_back(1);
        }
        return ans;
    }
};

struct Node
{
    int minindex;
    Node *next[20];
    Node() : minindex(INF)
    {
        memset(next, 0, sizeof(next));
    }
};

struct Trie
{
    Node *root;
    Trie()
    {
        root = new Node();
    }
    ~Trie()
    {
        clear(root);
    }
    void clear(Node *cur)
    {
        for (int i = 0; i < 10; i++)
        {
            if (cur->next[i] != NULL)
            {
                clear(cur->next[i]);
            }
        }
        delete cur;
    }
    void insert(string s, int index)
    {
        Node *cur = root;
        int j = 0;
        for (int i = 0; i < s.size(); i++)
        {
            int a = s[i] - '0';
            if (cur->next[a] == NULL)
            {
                cur->next[a] = new Node();
            }
            cur = cur->next[a];
            cur->minindex = min(cur->minindex, index);
        }
    }
    int search(char s[])
    {
        Node *cur = root;
        int len = strlen(s);
        for (int i = 0; i < len; i++)
        {
            if (cur->next[s[i] - '0'] == NULL)
            {
                return -1;
            }
            else
            {
                cur = cur->next[s[i] - '0'];
                if (i == len - 1)
                {
                    return cur->minindex;
                }
            }
        }
    }
};

Trie fibtrie;

void calfib()
{
    BigInteger a(1);
    fibtrie.insert(a.tostring(), 0);
    BigInteger b(1);
    fibtrie.insert(b.tostring(), 1);
    BigInteger c;
    for (int i = 2; i < maxn; i++)
    {
        c = a + b;
        fibtrie.insert(c.tostring(), i);
        a = b;
        b = c;
    }
}

int main()
{
    calfib();
    int T;
    cin >> T;
    char s[100];
    for (int cases = 1; cases <= T; cases++)
    {
        scanf("%s", s);
        printf("Case #%d: %d\n", cases, fibtrie.search(s));
    }
    return 0;
}

你可能感兴趣的:(解题笔记)