51Nod-1126 求递推序列的第N项
基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
收藏
关注
有一个序列是这样定义的:f(1) = 1, f(2) = 1, f(n) = (A * f(n - 1) + B * f(n - 2)) mod 7.
给出A,B和N,求f(n)的值。
Input
输入3个数:A,B,N。数字之间用空格分割。(-10000 <= A, B <= 10000, 1 <= N <= 10^9)
Output
输出f(n)的值。
Input示例
3 -1 5
Output示例
6
因为N=10^9太大,所以肯定不是用F[N]直接输出的= =、
这题肯定是有循环的。那么只需要找出它(循环的起始点)和(循环的大小)就可以了。
★TIP:————————————————————————此类题目的循环的起始点不一定是f(1),f(2)★——————————————————————————————这里着重强调
1 #include<stdio.h> 2 #include<string.h> 3 int s[10000000]; 4 int main() 5 { 6 int flag[8][8];//标记循环点开始的位子 7 int cnt=0;//标记循环点第一次重复后的位子 8 long long A,B,N; 9 scanf("%lld%lld%lld",&A,&B,&N); 10 memset(flag,0,sizeof(flag)); 11 s[1]=1;s[2]=1; 12 int i; 13 for(i=3;i<50;i++)//7*7=49 14 { 15 s[i]=((A*s[i-1]+B*s[i-2])%7+7)%7; 16 if(s[i]==1&&s[i-1]==1)//循环点是1 1开始的 17 break; 18 if(flag[s[i]][s[i-1]])//循环点不是1 1开始的话 19 { 20 cnt=flag[s[i]][s[i-1]]; 21 break; 22 } 23 flag[s[i]][s[i-1]]=i; 24 } 25 if(N<i)//如果再循环点内直接输出 26 { 27 printf("%d\n",s[N]); 28 } 29 else if(cnt)//如果循环点不是1 1开始的话 30 { 31 printf("%d\n",s[(N-cnt)%(i-cnt)+cnt]); 32 } 33 else 34 { 35 i=i-2; 36 if(N%i==0)//防止s[0]这样的 37 printf("%d\n",s[i]); 38 else 39 printf("%d\n",s[N%i]); 40 } 41 return 0; 42 }