题意:就是让你求斐波拉切数列的第n项的后面四位。
分析:但是n比较大,所以用数组是无法保存的,题目中已经给出了矩阵的表示方法,这是我做的第一道关于矩阵的乘法的题目,算法设置很巧妙,矩阵二分最基础也是最经典的题目,构造方法很多,由于F[n] = F[n-1] + F[n-2];
|F[n] F[n-1] | | 1 1 | |F[n+1] F[n] |
| | * | | =
|F[n-1] F[n-2] | | 1 0 | |F[n] F[n-1] |
于是我们就可以得出每次相乘之后矩阵的第一个元素就是斐波拉切数列的下一个值,但是如果一直乘下去,时间复杂度很高,于是我们想到了快速幂运算。
代码实现:
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; struct node{ int p[2][2]; }; struct node a,b; struct node yun(struct node a,struct node b) { struct node c; int i,j,k; for(i=0;i<2;i++)//矩阵相乘 for(j=0;j<2;j++) { c.p[i][j]=0; for(k=0;k<2;k++) c.p[i][j]=(c.p[i][j]+a.p[i][k]*b.p[j][k])%10000; } return c; } void haha(int n)//幂的快速运算 { while(n) { if(n&1) b=yun(b,a); n=n/2; a=yun(a,a); } printf("%d\n",b.p[0][0]); } int main() { int n; while(scanf("%d",&n)!=EOF&&n!=-1) { if(n==0) { printf("%d\n",0); continue; } a.p[0][0]=a.p[0][1]=1;// a.p[1][0]=1;a.p[1][1]=0; b.p[0][0]=1;b.p[0][1]=0; b.p[1][0]=0;b.p[1][1]=1; haha(n-1); } return 0; }
http://www.matrix67.com/blog/archives/276