hdoj4099(字典树+高精度)

题目链接:https://vjudge.net/problem/HDU-4099

题意:给T组询问,每个询问为一个字符串(长度<=40),求以该字符串为开始的fibonacci数列的第一个元素的下标,如果在前100000项里都没有,输出-1。

思路:
  首先是fibonacci数列这一部分,要用高精度先处理出前1e5项,但显然不能保留每一项的所有位,因为前缀只有40位,我们也只需要计算数列的前40位,为了保证前40位的正确,我计算到了70位。

  然后是字典树记录前缀,字典树大概最多40层,空间1e7左右

AC code:

#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;

int compare(string str1,string str2){
    int len1=str1.length(),len2=str2.length();
    if(len1<len2)
        return -1;
    else if(len1>len2)
        return 1;
    else
        return str1.compare(str2);
}

char c[205];
void add(char *a,char *b,char *back)
{
    int i = (int)strlen(a) - 1,j = (int)strlen(b) - 1;
    int x = 0,y = 0,z = 0,up = 0,cnt = -1;
    while(i >= 0 || j >= 0)
    {
        if(i < 0)x = 0;
        else x = a[i] - '0';

        if(j < 0)y = 0;
        else y = b[j] - '0';

        z = x + y + up;
        c[++cnt] = z % 10 + '0';
        up = z / 10;
        i--;j--;
    }
    if(up > 0)
        c[++cnt] = up + '0';
    for(int i = 0;i <= cnt;i++)
        back[i] = c[cnt - i];
    back[++cnt] = '\0';
}

const int maxn=1e5+5;
const int maxm=1e7+5;
string str[3];
char s[50];
int tot,T,cas,cnt,trie[maxm][12],key[maxm];

void insert(char* s,int k){
    int len=min((int)strlen(s),43),u=0;
    for(int i=0;i<len;++i){
        int t=s[i]-'0';
        if(!trie[u][t]){
            ++cnt;
            key[cnt]=k;
            trie[u][t]=cnt;
        }
        u=trie[u][t];
    }
}

int query(char *s){
    int len=strlen(s),u=0;
    for(int i=0;i<len;++i){
        int t=s[i]-'0';
        if(!trie[u][t])
            return -1;
        u=trie[u][t];
    }
    return key[u];
}

void init()
{
    tot = 1;
    char a[205],b[205],ans[205];
    a[0] = b[0] = '1';a[1] = b[1] = 0;
    insert(b,0);
    for(int i = 2;i < 100000;++i)
    {
        if(strlen(b) > 70)
        {
            b[strlen(b) - 1] = 0;
            a[strlen(a) - 1] = 0;
        }
        add(a,b,ans);
        insert(ans,i);
        strcpy(a,b);
        strcpy(b,ans);
    }
}

int main(){
    init();
    scanf("%d",&T);
    while(T--){
        scanf("%s",s);
        printf("Case #%d: %d\n",++cas,query(s));
    }
    return 0;
}

 

posted @ 2019-11-13 11:11  Frank__Chen  阅读(159)  评论(0编辑  收藏  举报