hdu4099Revenge of Fibonacci 字典树+Fibnocci

来源:互联网 发布:信用卡账单伪造软件 编辑:程序博客网 时间:2024/06/03 19:53

//思路:

//首先利用大数相加暴力求解前100000的Fabnocci数列, 并把每一个数列插入到字典树中

//然后对每一个输入在字典树中进行查找,若找到则返回下标最小的数,若没有找到则返回-1

//注意:1)大数相加的过程中,由于题目求的是最高位的前40位,但是由于空间性能,我们可以数列精确到前55位即可,否则空间不够用

//                  精确到50多位是为了防止出现进位溢出

//            2)在Node结构体中, struct Node_ * next[10];是10个表示0-9,以前习惯用N = 10, 这次忘了, 误用这里的宏定义N, 因为N= 55, 就这一点错误Wrong了好几次;

#include <iostream>#include <stdlib.h>#include <string.h>using namespace std;#define N 55#define BASE 10typedef struct Node_{Node_(){id = -1;memset(next, 0, sizeof(next));}int id;struct Node_ * next[10];}Node;Node * root = 0;int fb1[N] = {0};int fb2[N] = {0};int fb3[N] = {0};char num[N] = {0};int tree_insert(char * word, int id){if (root == 0){root = new Node();}int len = strlen(word);Node * tmpNode = root;int site = 0;for (int i = 0;i < len;i++){site = word[i] - '0';if (tmpNode->next[site] == 0){tmpNode->next[site] = new Node();}tmpNode = tmpNode->next[site];if (tmpNode->id == -1){tmpNode->id = id;}}return 1;}int tree_search(char * word){Node * tmpNode = root;int len = strlen(word);int site = 0;for (int i = 0; i< len; i++){site = word[i] - '0';if (tmpNode->next[site] == 0){return -1;}tmpNode = tmpNode->next[site];}return tmpNode->id;}//利用大数相加暴力求解前100000的Fabinaci数列void InitFibnaci(){int i, j, k,carry, m;fb2[0] = 1;fb3[0] = 1;num[0] = '1';num[1] = 0;tree_insert("1", 0);//由于fb[0] = fb[1] = 1;//所以tree_insert("1", 1),省去了for (i = 2;i < 100000; ++i){// fb1[0]表示低位,fb1[n]表示高位carry = 0;memset(fb1, 0, sizeof(fb1));for (j = 0; j < N; ++j){fb1[j] = fb2[j] + fb3[j] + carry;carry = fb1[j] / BASE;fb1[j] %= BASE;}j = N-1;while(j >= 0 && fb1[j] == 0){j--;}m = j;for (k = 0;j >= 0 && k < 40; j--){num[k++] = fb1[j] + '0';}num[k] = 0;tree_insert(num, i);//为了防止溢出,所以只要fb1的最高位大于50就把最低位左移一位if (m > 50){for (j = 1;j  < N; ++j){fb1[j - 1] = fb1[j];fb2[j - 1] = fb2[j];}}memcpy(fb3, fb2, sizeof(fb2));memcpy(fb2, fb1, sizeof(fb1));}}int main(){int t, n, q, i, j, len;char tmpStr[N * 2];    InitFibnaci();while(scanf("%d", &n) != EOF){for (i = 1;i <= n; ++i){scanf("%s", tmpStr);printf("Case #%d: %d\n", i, tree_search(tmpStr));}}return 0;}


原创粉丝点击