HDU-4099Revenge of Fibonacci (高精度加法&&字典树)

传送门

11年上海区域赛题

 

T组数据,求对于每个数,求最小的n使得该数为斐波那契数列第n位的前缀,若n大于100000,输出-1

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 const int maxn = 4e6 + 10;
 6 const int maxsize = 10;
 7 
 8 int ch[maxn][maxsize];
 9 int val[maxn];
10 int A[60];
11 int B[60];
12 char s[100];
13 
14 int T;
15 
16 struct Trie {
17     int sz;
18     Trie() {
19         sz = 1;
20         memset(ch[0], 0, sizeof(ch[0]));
21         memset(val, -1, sizeof(val));
22     }
23     int idx(char c) {return c - '0';}
24 
25     void insert(int* a, int len, int v) {
26         int u = 0;
27         for (int i = len - 1; i >= max(0, len - 40); i--) {
28             int c = a[i];
29             if (!ch[u][c]) {
30                 memset(ch[sz], 0, sizeof(ch[sz]));
31                 ch[u][c] = sz++;
32             }
33             u = ch[u][c];
34             if (val[u] == -1) {
35                 val[u] = v;
36             }
37         }
38     }
39 
40     int find(char* s) {
41         int len = strlen(s);
42         int u = 0;
43         for (int i = 0; i < len; i++) {
44             int c = idx(s[i]);
45             if (!ch[u][c]) {
46                 return -1;
47             }
48             u = ch[u][c];
49         }
50         return val[u];
51     }    
52 
53 };
54 
55 Trie Tree;
56 
57 
58 int main() {
59     memset(A, 0, sizeof(A));
60     memset(B, 0, sizeof(B));
61     B[0] = 1;
62     int len1 = 1;
63     int len2 = 1;
64     for (int n = 0; n < 100000; n++) {
65         Tree.insert(B, len2, n);
66         int len3 = len2;
67         for (int i = 0; i < len3; i++) {
68             A[i] += B[i];
69             if (A[i] >= 10) {
70                 A[i] -= 10;
71                 A[i + 1]++;
72             }
73         }
74         if (A[len3]) len3++;
75         if (len3 == 51) {
76             len3--;
77             for (int i = 0; i < len3; i++) {
78                 A[i] = A[i + 1];
79             }
80             A[50] = 0;
81             len2--;
82             for (int i = 0; i < len2; i++) {
83                 B[i] = B[i + 1];
84             }
85             B[len2] = 0;
86         }
87 
88         swap(A, B);
89         len1 = len2;
90         len2 = len3;
91 
92     }
93     scanf("%d", &T);
94     for (int i = 1; i <= T; i++) {
95         scanf("%s", s);
96         printf("Case #%d: %d\n", i, Tree.find(s));
97     }
98     return 0;
99 }

 

posted @ 2018-03-07 12:22  xFANx  阅读(100)  评论(0编辑  收藏  举报