HDU - 4099 Revenge of Fibonacci(模拟竖式,精度)

🎴 🎴 🎴

真不好调,值得注意的一点就是题目说明给出的前缀最多只有四十位,所以我们建立字典树的时候也只取前四十位即可,加和的时候保留60位。

int f[2][MAXN];//滚动数组
char s[55],n[444];
int tot,son[MAXN*43][10];
int mp[MAXN*44];
void build(int k)
{
    int p=0,len=strlen(s);
    rep(i,len)
    {
        int c=s[i]-'0';
        if(son[p][c]==0) son[p][c]=++tot;
        p=son[p][c];
        if(mp[p]==0) mp[p]=k+1;
    }
}
void init()
{
    int low=0,high=1;//最低位最高位
    f[0][0]=1,f[1][0]=1;
    s[0]='1';s[1]=0;
    build(0);
    for(int k=2;k<100000;++k)
    {
        for(int i=low;i<high;++i)
        {
            f[0][i]+=f[1][i];
            if(f[0][i]>=10&&i==high-1) ++high;
            f[0][i+1]+=f[0][i]/10;
            f[0][i]%=10;
        }
        if(high-low>60) ++low;
        for(int i=low;i<high;++i) swap(f[0][i],f[1][i]);
        for(int i=high-1,j=0;i>=low&&j<=40;--i,++j) s[j]=f[1][i]+'0';
        build(k);
        memset(s,0,sizeof(s));
    }
}
int solve()
{
    int len=strlen(n);
    int p=0,ans=-1;
    for(int i=0;i<len;++i)
    {
        int c=n[i]-'0';
        if(son[p][c]) p=son[p][c];
        else return -1;
        ans=mp[p];
    }
    return ans-1;
}
signed main()
{
    init();
    int T;cin>>T;
    rpp(_,T)
    {
        cin>>n;
        printf("Case #%d: %d\n",_,solve());
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值