【HDU 1005】Number Sequence

 

Number Sequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 137129    Accepted Submission(s): 33238


Problem Description
A number sequence is defined as follows:

f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.

Given A, B, and n, you are to calculate the value of f(n).
 

 

Input
The input consists of multiple test cases. Each test case contains 3 integers A, B and n on a single line (1 <= A, B <= 1000, 1 <= n <= 100,000,000). Three zeros signal the end of input and this test case is not to be processed.
 

 

Output
For each test case, print the value of f(n) on a single line.
 

 

Sample Input
1 1 3 1 2 10 0 0 0
 

 

Sample Output
2 5

 

 

        第一道水题,大意是求f(n) mod 7的值。看起来像斐波那契数列,而且数值非常大,排除了函数和数组的初级方法,第一反应是矩阵快速幂,但是以为A和B的存在,这种方法也行不通(至少我没想到怎么做)。之后的想法就是找规律,因为f(n)的每一项都一定小于7,所以多写了几个发现总会有如下规律:

        假如A=1,B=2,n=10,f(n)分别为 1 1 3 5 4 0 1 1 3 5,不难发现从f(6)开始就成了一个循环,循环节是(1 1 3 5 4 0),所以只需要求n对于循环节长度的Mod值即可。

        Ps:循环节前可能会有前缀,不要忘记去掉。

 

#include <cstdio>
#include <cstring>
short int f[1000005];
int main()
{
    int a,b,n;
    while(~scanf("%d%d%d",&a,&b,&n))
    {
        if(a==0&&b==0&&n==0) break;
        memset(f,0,sizeof(f));
        f[1]=1,f[2]=1;
        bool flag=false;
        int qz=0,xh=0;
        for(int i=3; i<=n; i++)
        {
            f[i]=((a*f[i-1])%7+(b*f[i-2]%7))%7;
            for(int j=2;j<i;j++)   ///循环找是否有相同的数对
            {
                if(f[i-1]==f[j-1]&&f[i]==f[j])
                {
                    qz=j;         ///前缀的长度
                    xh=i-j;       ///循环体长度
                    flag=true;
                    break;
                }
            }
            if(flag) break;
        }
        if(!flag) printf("%d\n",f[n]);
        else printf("%d\n",f[qz+(n-qz)%xh]);
    }
}


 





 

posted @ 2015-12-02 19:31  Torrance_ZHANG  阅读(171)  评论(0编辑  收藏  举报