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;
    }
}

 

發佈了74 篇原創文章 · 獲贊 4 · 訪問量 5061
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章