一 问题描述
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).
二 解法
显然,由于取余的关系,连续的两个数f[i][j]( 0 <= i,j <= 6)出现的情况最多7×7=49种,故只要知道前51个数,定能够出现一个循环节(鸽巢原理)。
故只要记录下出现重复对的起始位置start,求得循环节长度len,就能确定第n个数
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
int a[52];
bool f[7][7];
int main()
{
freopen("in.txt", "r", stdin);
int A,B,n;
int i,j,len;
int start;
while (cin >> A >> B >> n)
{
if (!A || !B || !n)
break;
for (i = 0; i < 7; i++)
for (j = 0; j < 7; ++j)
f[i][j]=false;
a[1] = 1;
a[2] = 1;
f[1][1] = true;
for (i = 3; i <= 100; ++i)
{
a[i] = (A*a[i-1]+B*a[i-2])%7;
if (f[a[i-1]][a[i]])
{
for (j = 2; j < i; ++j)
{
if ((a[j-1] == a[i-1]) && (a[j] == a[i]))
{
len = i - j;
start = j-2;
break;
}
}
break;
}
else
f[a[i-1]][a[i]] = true;
}
// cout << start << endl;
if (n <= start)
cout << a[n] << endl;
else
{
if ((n - start)%len == 0)
cout << a[1 + start] << endl;
else
cout << a[(n - start)%len + start] << endl;
}
}
return 0;
}