码迷,mamicode.com
首页 > 其他好文 > 详细

HDU1005 找规律 or 循环点 or 矩阵快速幂

时间:2017-12-20 03:54:24      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:amp   pid   can   nbsp   而且   namespace   范围   之间   不同   

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\n",f[(n-1)%1008+1]);   

    }   

    return 0;   

}  

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

未解之谜……待续。

HDU1005 找规律 or 循环点 or 矩阵快速幂

标签:amp   pid   can   nbsp   而且   namespace   范围   之间   不同   

原文地址:http://www.cnblogs.com/Cloud-king/p/8067796.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!