zoukankan      html  css  js  c++  java
  • bzoj1002 [FJOI2007]轮状病毒——找规律+高精度

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1002

    打表找规律,似乎是这样:https://blog.csdn.net/fzhvampire/article/details/46389897

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n;
    struct N{
        int a[50005];
        N(){memset(a,0,sizeof a);}
    }f[105],ans;
    N add(N x,N y)
    {
        N ret;
        ret.a[0]=max(x.a[0],y.a[0]);
        for(int i=1;i<=ret.a[0];i++)
            ret.a[i]=x.a[i]+y.a[i];
        for(int i=1;i<=ret.a[0];i++)
        {
            int t=ret.a[i]/10; ret.a[i]%=10;
            ret.a[i+1]+=t;
        }
        if(ret.a[ret.a[0]+1])ret.a[0]++;
        return ret;
    }
    N pw(N x)
    {
        N ret;
        ret.a[0]=2*x.a[0];
        for(int i=1;i<=x.a[0];i++)
            for(int j=1;j<=x.a[0];j++)
                ret.a[i+j-1]+=x.a[i]*x.a[j];
        for(int i=1;i<=ret.a[0];i++)
        {
            int t=ret.a[i]/10; ret.a[i]%=10;
            ret.a[i+1]+=t;
        }
        if(ret.a[ret.a[0]+1])ret.a[0]++;
        while(ret.a[ret.a[0]]==0&&ret.a[0])ret.a[0]--;
        return ret;
    }
    void sub(int k)
    {
        ans.a[1]-=k; int i=1;
        while(ans.a[i]<0)ans.a[i]+=10,ans.a[++i]--;
        while(ans.a[ans.a[0]]==0&&ans.a[0])ans.a[0]--;
    }
    void print()
    {
        for(int i=ans.a[0];i;i--)printf("%d",ans.a[i]);
    }
    int main()
    {
        scanf("%d",&n);
        f[1].a[0]=1; f[1].a[1]=1;
        f[2].a[0]=1; f[2].a[1]=3;
        for(int i=3;i<=n;i++)
            f[i]=add(f[i-1],f[i-2]);
        ans=pw(f[n]);
        if(n%2==0)sub(4);
        print();
        return 0;
    }

    还有大家都在说的结论:http://vfleaking.blog.163.com/blog/static/17480763420119685112649/

    也就是:f[i] = ( f[i-1]*3 - f[i-2] + 2 )

    代码如下:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    int n;
    struct N{
        int a[50005];
    //    N(){memset(a,0,sizeof a);}
    }f[105],ans;
    N sub(N x,N y)
    {
        x.a[1]+=2;
        int j=1;
        while(x.a[j]>=10){x.a[j]%=10;x.a[j+1]++;j++;} 
        for(int i=1;i<=x.a[0];i++)
        {
            x.a[i]-=y.a[i];
            if(x.a[i]<0)x.a[i]+=10,x.a[i+1]--;
        }
    //    for(int i=1;i<=x.a[0];i++)
    //        if(x.a[i]<0)x.a[i]+=10,x.a[i+1]--;
        while(x.a[x.a[0]]==0&&x.a[0])x.a[0]--;
        return x;
    }
    //N add(N x,int k)
    //{
    //    x.a[1]+=k; int i=1;
    //    while(x.a[i]>=10)x.a[i+1]+=x.a[i]/10,x.a[i]%=10,i++;
    //    if(x.a[x.a[0]+1])x.a[0]++;
    //    return x;
    //}
    N mul(N x,int k)
    {
        for(int i=1;i<=x.a[0];i++)x.a[i]*=k;
        for(int i=1;i<=x.a[0];i++)
        {
            x.a[i+1]+=x.a[i]/10; x.a[i]%=10;
        }
        if(x.a[x.a[0]+1])x.a[0]++;
        return x;
    }
    void print()
    {
        for(int i=f[n].a[0];i;i--)printf("%d",f[n].a[i]);
    }
    int main()
    {
        scanf("%d",&n);
        f[1].a[0]=1; f[1].a[1]=1;
        f[2].a[0]=1; f[2].a[1]=5;
        for(int i=3;i<=n;i++)
        {
    //        f[i]=mul(f[i-1],3);
    //        f[i]=sub(f[i],f[i-2]);
    //        f[i]=add(f[i],2);
            f[i]=sub(mul(f[i-1],3),f[i-2]);
        }
        print();
        return 0;
    }

    果然考场上还是打表找规律比较靠谱...

    然而为什么,我的代码跑得好慢...

  • 相关阅读:
    GeoMesa Java API-写入与查询数据
    GeoMesa命令行,索引概述
    HBase,以及GeoMesa设计基于HBase的设计分析,从数据模型到典型查询场景,最后进行RowKey设计
    笔趣看小说Python3爬虫抓取
    python网络爬虫
    Kafka客户端Producer与Consumer
    ScalikeJDBC,操作mysql数据,API
    mysqldb
    Python 反射
    Go 类型转换
  • 原文地址:https://www.cnblogs.com/Zinn/p/9252831.html
Copyright © 2011-2022 走看看