首先暴力打表就很容易发现有循环节,于是一开始的写法是直接暴力找循环节,结果一直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; }
时间: 2024-12-12 12:26:36