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 ", i, Tree.find(s)); 97 } 98 return 0; 99 }