题目:https://vjudge.net/problem/UVA-12333
思路: 大整数类+字典树
一开始套刘汝佳大整数类的板子套出好多问题,之后自己用string重新封装了一个。
用大整数类求出斐波那契数列然后将前42位插入字典树,便于之后查找前缀。
这题做出了灵异事件,在自己机器上预处理好几分钟都跑不完结果交上去竟然AC了。。。。。
代码:c++
#include <cstdio>
#include <iostream>
#include <cstring>
#include <vector>
#include <algorithm>
#include <string>
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;
}