zoukankan      html  css  js  c++  java
  • HDU1005 找规律 or 循环点 or 矩阵快速幂

    http://acm.hdu.edu.cn/showproblem.php?pid=1005

    1.一开始就注意到了n的数据范围 <=100 000 000,但是还是用普通的循环做的,自然TLE了,然后朴素打表,= =运行不了,(怎么可能能把数组开到那么大)。再然后就想到了寻找下一个1 1 连续在一起的,那就能开始下一轮循环了。

    但是,各种WA……(将数组开大一点,寻找到a[ i ] = a[ i -1 ] ==1 即跳出),这个AC代码将102改成100,150,200都可以,但是108,49 ,204什么的就不行。

    其实也可能数组并不是从11开始循环的,而是后面出现了两组相邻相同的非1 1数,循环则从最先出现两组相邻对等的数开始循环。如1 1 …………X X…………X X…………然后循环就从XX开始循环,不关1 1什么事儿了,但是下面这个代码却能AC而且数组的长度(maxn)有一定限制,有些能有些不能(???)。

    #include <cstdio>
    #include <iostream>
    #define maxn 102
    
    using namespace std;
    
    int num[maxn];
    int main()
    {
        int a,b,n,i=3;
        num[0]=1;    num[1]=1;    num[2]=1;
        while(~scanf("%d%d%d",&a,&b,&n),a||b||n)
        {
            i=3;
            for(i=3;i<maxn;i++)
            {
                num[i]=(a*num[i-1]+b*num[i-2])%7;
                if(num[i]==1&&num[i-1]==1)
                    break;
            }
            num[0]=num[i-2];
            n%=i-2;
            cout << num[n] << endl;
        }
        return 0;
    }

    然后就看有说fn =fn-1 + fn-2 再对7取模,其中的f 项都是0 - 6 之间的数,所以 两数相加之和再取模,最多有7*7种可能后必定会fn-1 与 fn-2 的值的情况与前面的有重复,所以循环节为49 ,这感觉是最容易接受也最为合理的一种解释。

    然后就有了如下AC代码,其中maxn为48,49均可(???)。

    #include <cstdio>
    #include <iostream>
    #define maxn 48
    
    using namespace std;
    
    int num[maxn];
    int main()
    {
        int a,b,n,i=3;
        num[0]=1;    num[1]=1;    num[2]=1;
        while(~scanf("%d%d%d",&a,&b,&n),a||b||n)
        {
            i=3;
            for(i=3;i<=maxn;i++)
            {
                num[i]=(a*num[i-1]+b*num[i-2])%7;
                /*if(num[i]==1&&num[i-1]==1)
                {
                    //cout << i << endl;
                    break;
                }*/
            }
            num[0]=num[maxn];
            cout << num[n%maxn] << endl;
        }
        return 0;
    }

     再然后就是矩阵快速幂了,占坑,(回来学= =)。

    最后贴个暴力代码(网上搜的,这个厉害了= =),一个个试,找到他们不同的A,B下他们的周期的最小公倍数为1008。

    #include<iostream>   
    
    using namespace std;   
    
    int main()   
    
    {   
    
        int a,b,n,i;   
    
        while(scanf("%d%d%d",&a,&b,&n)&&a&&b&&n)   
    
        {   
    
            int f[1009];   
    
            f[1]=1;   
    
            f[2]=1;   
    
            for(i=3;i<=1008;i++)   
    
            {   
    
                f[i]=(a*f[i-1]+b*f[i-2])%7;   
    
            }   
    
            printf("%d
    ",f[(n-1)%1008+1]);   
    
        }   
    
        return 0;   
    
    }  

     以上为做了耗了我几个小时的hdu1005(不知道值不值= =)。

    未解之谜……待续。

  • 相关阅读:
    《瓦尔登湖》读书随笔
    Ubuntu下nginx+uwsgi+flask的执行环境搭建
    Android studio SweetAlert for Android
    mysql 主从不同步处理--数据库初始化
    Nginx学习——http配置项解析编程
    支付宝集分宝接口开发的相关问题解答
    解读刘强东关于人才的两个标准和5个层次
    oc35--自定义构造方法
    oc34--instancetype和id的区别
    oc33--构造方法2
  • 原文地址:https://www.cnblogs.com/Cloud-king/p/8067796.html
Copyright © 2011-2022 走看看