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)是由f(n-1)、f(n-2)求出来的,所以只要有一对连续的数与之前重复就会循环,由于f(n)是mod 7得到的,所以f(n)一定是0、1、2、3、4、5、6这7个数中的某个数,那么连续两个数的有序组合最多有7*7=49种,就可以通过求前面有限的几项f(n),寻找周期。这里要注意周期开始的两个数是不确定的,不要以为周期一定是从1 1开始,刚开始的时候以为周期一定是从1 1开始的错了很多次,应该每计算出一个数就寻找前面有没有相同的有序组合,一旦有周期就找到了,周期可能不是1 1开始,1 1也不一定在周期内。
代码:
#include <stdio.h>
int main()
{
int findloop(int arr[],int ,int);
int A,B,N,i,j;
int f[101];
while(scanf("%d %d %d",&A,&B,&N),A||B||N)
{
i=3;
f[1]=1;
f[2]=1;
for(i=3;i<=N;i++)
{
f[i]=(A*f[i-1]+B*f[i-2])%7;
j=findloop(f,i,N);
if(j)
{
N=j;
break;
}
}
printf("%d\n",f[N]);
}
return 0;
}
int findloop(int arr[],int i,int N)
{
intj;
for(j=2;j<=i-2;j++)
{
if(arr[i]==arr[j]&&arr[i-1]==arr[j-1])
{
N=(N-(j-2))%(i-j);
if(N==0)
N=i-j;
returnN+j-2;
}
}
return 0;
}
ps:这道题还可以把f(1)当做周期的开始,周期长度336,336并不是唯一的数,还可以比它大,它只不过是一个最小的数。336是1、2、3、4、6、8、12、14、16、21、24、42、48的最小公倍数。其实一开始的时候看到有别人做的是以1008为周期,不知道为什么,想到与公倍数有关,可是1到49的最小公倍数太大与1008相差太远,不明白为什么以1008为周期,经过问别人才得到最小是336,那些数是写了个程序将1<=A,B<=1000的每一种组合的周期都找到得出来的。