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 }

 



posted @ 2018-07-17 16:02  jealous-boy  阅读(320)  评论(0编辑  收藏  举报