Number Sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 64297 Accepted Submission(s): 14829
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).
1 1 3 1 2 10 0 0 0
2 5
分析:寻找循环节点,就是找到规律,因为结果是0到6之间的数,所以一定会循环,而且循环节不会超过49。(因为前面2个数若相同,则第三个之后的数必相同,而在49内必能找到2个相邻的数在前面出现过)。不是很懂这个规律,也是看别人的。我再试试矩阵的乘法。
代码:
#include<stdio.h> int main() { int A,B,n; int s[100]; while(scanf("%d%d%d",&A,&B,&n)) { if(A==0&&B==0&&n==0) break; int i; s[0]=s[1]=1; for(i=2;i<50;i++) { s[i]=(A*s[i-1]+B*s[i-2])%7; if(s[i]==1&&s[i-1]==1) break; } n=n%(i-1); if(n==0) printf("%d\n",s[i-2]); else printf("%d\n",s[n-1]); } return 0; }
代码:利用矩阵乘法和快速幂实现
| f(1) f(2)| * |0 b |^(n-1) =| f(n) f(n+1)|
| f(2) f(3)| | 1 a | |f(n+1) f(n+2)|
#include<stdio.h>
struct Matrix
{
int row[2][2];
};
Matrix A,B,ans;
int a,b,n;
void Init()
{
A.row[0][0]=1;
A.row[0][1]=1;
A.row[1][0]=1;
A.row[1][1]=(a+b)%7;
B.row[0][0]=0;
B.row[0][1]=b;
B.row[1][0]=1;
B.row[1][1]=a;
}
Matrix Multiply(Matrix t1,Matrix t2)
{
Matrix sum;
int i,j;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
sum.row[i][j]=(t1.row[i][0]*t2.row[0][j]+t1.row[i][1]*t2.row[1][j])%7;
return sum;
}
void kuaisu(int times)//快速幂
{
ans=B;
while(times)
{
if(times&1)//若times是奇数则先跟A相乘,那么times就相当于降了一阶
A=Multiply(A,ans);
ans=Multiply(ans,ans);//B^times(times是偶数)可以变成(B*B)^(times/2)这就是快速幂的思想
times>>=1;//把times除以2
}
}
int main()
{
while(scanf("%d%d%d",&a,&b,&n)!=EOF&&(a||b||n))
{
Init();
kuaisu(--n);
printf("%d\n",A.row[0][0]);
}
return 0;
}