zoukankan      html  css  js  c++  java
  • HDU 4099 Revenge of Fibonacci(高精度+字典树)

    题意:对给定前缀(长度不超过40),找到一个最小的n,使得Fibonacci(n)前缀与给定前缀相同,如果在[0,99999]内找不到解,输出-1。

    思路:用高精度加法计算斐波那契数列,因为给定前缀长度不超过40,所以高精度计算时每次只需保留最高60位,每次将得到的值插入到字典树中,使得树上每个节点只保留最小的n值。查询输出字典树结点的值。

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define MAXNLEN 80
    #define LEN 60
    using namespace std;
    
    struct bign
    {
        int d[MAXNLEN],len;
    };
    
    void add(bign & a,bign & b,bign & c)
    {
        c.len=max(a.len,b.len);
        int carry=0;
        for(int i=0;i<c.len;++i)
        {
            int now=carry+(i<a.len)*a.d[i]+(i<b.len)*b.d[i];
            c.d[i]=now%10;
            carry=now/10;
        }
        if(carry) c.d[c.len++]=1;
    
        if(c.len>LEN)
        {
            for(int i=0;i<LEN;++i) c.d[i]=c.d[i+1]; --c.len;
            for(int i=0;i<LEN;++i) a.d[i]=a.d[i+1]; --a.len;
            for(int i=0;i<LEN;++i) b.d[i]=b.d[i+1]; --b.len;
        }
    }
    bign tmp[3];
    
    #define maxnode 4100000
    #define sigema_size 10
    struct Trie
    {
    	int ch[maxnode][sigema_size],val[maxnode],sz;
    	Trie() {sz=1;memset(ch[0],0,sizeof(ch[0]));memset(val,-1,sizeof(val));}
    	void insert(bign s,int v)
    	{
    		int u=0;
    		for(int i=s.len-1;i>=max(s.len-41,0);--i)
    		{
    			int c=s.d[i];
    			if(!ch[u][c])
    			{
    				memset(ch[sz],0,sizeof(ch[sz]));
    				if(val[sz]==-1) val[sz]=v;
    				ch[u][c]=sz++;
    			}
    			u=ch[u][c];
    		}
    	}
    
    	int find(char *s)
    	{
    		int u=0;
    		for(int i=0;s[i];++i)
    		{
    			int c=s[i]-'0';
    			if(!ch[u][c]) return -1;
    			u=ch[u][c];
    		}
    		return val[u];
    	}
    }trie;
    
    void init()
    {
        tmp[0].len=tmp[1].len=1,tmp[0].d[0]=tmp[1].d[0]=1;
        trie.insert(tmp[1],0);
        for(int i=2;i<100000;++i)
        {
            add(tmp[(i+2)%3],tmp[(i+1)%3],tmp[i%3]);
            trie.insert(tmp[i%3],i);
        }
    }
    int T,ca=0;
    char st[MAXNLEN];
    int main()
    {
        init();
        scanf("%d",&T);
        while(T--)
        {
            scanf("%s",st);
            printf("Case #%d: %d
    ",++ca,trie.find(st));
        }
        return 0;
    }
  • 相关阅读:
    阿里云ECS磁盘性能测试
    阿里云NAS性能测试
    Jumpserver堡垒机容器化部署
    k8s集群中部署RookCeph高可用集群
    使用GitHub Action进行打包并自动推送至OSS
    MYSQL ERROR 1118
    ORACLE cursor_sharing参数导致函数索引失效
    导出微信视频号的视频
    iPad作为扩展屏的几种方案
    AR VR MR XR
  • 原文地址:https://www.cnblogs.com/pangblog/p/3397923.html
Copyright © 2011-2022 走看看