POJ3070

求斐波那契数列第n项。

矩阵乘法裸题。

关于矩阵乘法某个矩阵只有一行或者一列的循环写法,可以先把三重写出来

for(int i=0;i<n;i++)
    for(int j=0;j<n;j++)
        for(int k=0;k<n;k++)
            c[i][j]+=a[i][k]*b[k][j];

如果前面矩阵只有1行,则删去所有i出现的地方


    for(int j=0;j<n;j++)
        for(int k=0;k<n;k++)
            c[j]+=a[k]*b[k][j];

 如果后面矩阵只有1列,则删去所有j出现的地方

for(int i=0;i<n;i++)
  
        for(int k=0;k<n;k++)
            c[i]+=a[i][k]*b[k];

宏定义memcpy时犯了一个弱智错误,写习惯了memset

一开始写成了

#define mc(a,b) memcpy(a,b,sizeof(a)) 

应该是

#define mc(a,b) memcpy(a,b,sizeof(b)) 

AC代码: 

#include <cstdio>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cstring>
#define ms(a,b) memset(a,b,sizeof(a))
#define mc(a,b) memcpy(a,b,sizeof(b)) 
using namespace std;
const int mod=10000;
void mul(int f[2],int a[2][2])
{
    int c[2];
    ms(c,0);
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            c[i]=(c[i]+1LL*f[j]*a[j][i])%mod;
    mc(f,c);
}
void mulself(int a[2][2])
{
    int c[2][2];
    ms(c,0);
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
            for(int k=0;k<2;k++)
            c[i][j]=(c[i][j]+1LL*a[i][k]*a[k][j])%mod;
    mc(a,c);
}
int main()
{
    int n;
    while(cin>>n&&n!=-1)
    {
        int f[2]={0,1},a[2][2]={{0,1},{1,1}};
        while(n)
        {
            if(n&1)
                mul(f,a);
            n>>=1;
            mulself(a);
        }
        cout<<f[0]<<endl;
    }
}

猜你喜欢

转载自blog.csdn.net/Luowaterbi/article/details/104126141