首页 > 代码库 > HDU 1005 Number Sequence (循环节)

HDU 1005 Number Sequence (循环节)


首先暴力打表就很容易发现有循环节,于是一开始的写法是直接暴力找循环节,结果一直WA,

原因是有的循环并不是从1,1开始的,详细有证明戳这里:http://acm.hdu.edu.cn/discuss/problem/post/reply.php?postid=19818&messageid=1&deep=0

于是借鉴了大神的思路,因为%7,故可用v[7][7]来记录 f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.这个状态。若出现相同的状态,则证明出现了循环节。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1005

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cctype>
#include<algorithm>
#include<string>
#define N 100
using namespace std;

int v[7][7]; 
int f[N]={0,1,1};
int main()
{
    int A,B,n;
    while(scanf("%d%d%d",&A,&B,&n),A+B+n)
    {
        int x=1,y=1,k=3;
        memset(v,0,sizeof(v));
        while(!v[x][y])
        {
            v[x][y]=k;//记录这种状态出现的位置。
            f[k]=(A*y+B*x)%7;
            x=y;
            y=f[k];
            k++;
        }
        int s=v[x][y];
        //因为循环可能不是从1,1开始,所以这里很重要。
        if(n<k) printf("%d\n",f[n]); 
        else printf("%d\n",f[(n-s)%(k-s)+s]);//k-s即周期T。
    }
    return 0;
}


HDU 1005 Number Sequence (循环节)