找规律的题目,找到循环节就可以了,循环节不一定是从f(1),f(2)开始的,可能是从中间开始的,比如一组很特殊的数据7,56,n。由题意可知,因为f(i)(i=1,2,...n)的取值范围为[0,6],所以f(i-1),f(i)的可能取值组合只有49种,从(0,0)到(6,6)。还有一种想法是用矩阵快速幂,估算一下可能可以,不过没有试过。
#include<iostream>
#include<cstring>
using namespace std;
int f[100];
int flag[7][7];//f(i-1)f(i)取值标志int
main(int argc, char* argv[]){
long long a, b, n;
while (cin >> a >> b >> n && n!=0) {
memset(f, 0, sizeof(f));
memset(flag, 0, sizeof(flag));
f[1] = 1;
f[2] = 1;
flag[1][1] = 2;
if (n == 1 || n == 2) {
cout << f[n] << endl;
continue;
}
int i = 3;
int looplength = 2;
while (i <= n) {
f[i]=(a*f[i - 1] + b*f[i - 2]) % 7;
if (flag[f[i-1]][f[i]] != 0)//如果取值标志已经存在,则说明找到循环
{
looplength = i - flag[f[i-1]][f[i]];//循环节的大小
f[flag[f[i - 1]][f[i]] - 2] = f[i - 2];//因为n%looplength可能为0
break;
}
flag[f[i-1]][f[i]] = i;
i++;
}
if (i == n + 1 || i == n)
cout << f[n] << endl;
else if (i < n)
cout << f[(n - flag[f[i - 1]][f[i]]+2) % looplength + flag[f[i - 1]][f[i]]-2] << endl;//中间有点长,其实就是求f(n)是循环节中的第几个,然后从循环节的第0个开始找到对应值
}
return 0;
}
hdoj1005_Number Sequence
最新推荐文章于 2022-10-06 13:20:27 发布