CSUOJ 1313: ZZY的寵物

Description

ZZY領養了一對剛剛出生的不知名小寵物..巨萌巨可愛!!...小寵物的生命爲5個單位時間並且不會在中間出意外翹辮子(如: 從0出生能活到5但活不到6)..小寵物經過2個單位時間成熟..剛剛成熟的一對小寵物能立即生育6只新的小寵物(如: 從0出生的一對在2時成熟並進行第一次生育)...小寵物是很忠誠的..不會在中途換伴侶..每對小寵物生育一次這一對的生育能力就會降低2個..也就是說一對小寵物在第二次生育時就只能生4個了..小寵物成熟後每個單位時間都會盡力的生育(例: 從0出生的一對..2時間生6個..3時間生4個..4時間生2個...5時間生不出..6時間這一對已經掛了..)..生育出來的新小寵物會繼續這個過程.. 
ZZY想知道從單位時間0開始..經過M個單位時間(時間爲M時)將有多少隻活着的小寵物(0時刻有2只小寵物)
因爲ZZY隱隱地覺得什麼地方怪怪的...所以請將這個數目mod 10000 

Input

多組數據讀到EOF
每組數據一行:  
M ( 0<=M<=2000000000 )
最多500組數據 

Output

每組輸出一行爲  Case 組號: 答案,即M時刻活着的小寵物個數%10000

Sample Input

012348

Sample Output

Case 1: 2Case 2: 2Case 3: 8Case 4: 12Case 5: 32Case 6: 528


根據題意建立這樣一種數列 根據題意建立這樣一種數列 根據題意建立這樣一種數列 根據題意建立這樣一種數列 根據題意建立這樣一種數列 ,數列從 0號開始 號開始 .. 代表第 0個單 位時間出生的小寵物 位時間出生的小寵物 位時間出生的小寵物 位時間出生的小寵物 ...1 代表在第 1個單位時間出生的小寵物 個單位時間出生的小寵物 個單位時間出生的小寵物 個單位時間出生的小寵物 .. 以 此類推 .. 將這個數列某項稱作 將這個數列某項稱作 將這個數列某項稱作 Z[x]
顯然 .. 當 x>=5 時.. 在第 x天活着的小寵物數量 天活着的小寵物數量 天活着的小寵物數量 sum[x] = sum[x] = sum[x] = sum[x] = sum[x] = z[x -5] + z[x -4] + z[x -3] +z[x -2] +z[x -1] + z[x]
再看根據題意 再看根據題意 再看根據題意 再看根據題意 再看根據題意 再看根據題意 z[x] = x z[x] = x z[x] = xz[x] = z[x z[x] = x z[x] = x-2]/2*6 + z[x 2]/2*6 + z[x 2]/2*6 + z[x 2]/2*6 + z[x2]/2*6 + z[x 2]/2*6 + z[x 2]/2*6 + z[x-3]/2*4 + 3]/2*4 + 3]/2*4 + 3]/2*4 + 3]/2*4 + 3]/2*4 + z[x -4]/2*2 = z[x -2]*3 + z[x -3]*2 + z[x -4]
顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公顯然這個式 子是一遞推的公... 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 那麼就可以用矩陣乘法來 求解這個遞推公式的第 解這個遞推公式的第 解這個遞推公式的第 解這個遞推公式的第 x項是多少 ... 觀察數 列建立關於這個遞推觀察數 列建立關於這個遞推觀察數 列建立關於這個遞推觀察數 列建立關於這個遞推觀察數 列建立關於這個遞推列的 "特徵 “矩陣 ..
M = 0 1 0 0 0 0

       0 0 1 0 0 0

       0 0 0 1 0 0

       0 0 0 0 1 0

       0 0 0 0 0 1

       0 0 1 2 3 0


 而初始值爲 0單位時間的出生情況 單位時間的出生情況 單位時間的出生情況 單位時間的出生情況 ... 可以自己遞推出來 可以自己遞推出來 可以自己遞推出來 ... 爲 A = { 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 } 0 , ,0 ,2 }
要求第 x天出生了多少就用 天出生了多少就用 天出生了多少就用 z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)...z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... z[x] = A*(M^x)... 矩陣乘法用 遞歸 2分來求解 分來求解 ... ...
要 求 sum(x)... 就分別求
出 z[x -5] ,z[x 5] ,z[x5] ,z[x 5] ,z[x -4] ,z[x 4] ,z[x4] ,z[x 4] ,z[x -3] ,z[x 3] ,z[x3] ,z[x 3] ,z[x -2] ,z[x 2] ,z[x2] ,z[x 2] ,z[x -1] ,z[x] 1] ,z[x]1] ,z[x] 1] ,z[x] 1] ,z[x]再將 這幾個值加起來就行了 這幾個值加起來就行了 這幾個值加起來就行了 這幾個值加起來就行了 ....


Code:

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define LL long long
using namespace std;
 
const int N = 52;
static int mod = 1111;
 
struct Matrix {
    int  mat[N][N]; //修改long long or int
    int n, m;
 
    Matrix() {//初始化,根據需要可以把此處刪除!
        n = m = N;
        memset(mat, 0, sizeof(mat));
    }
 
    inline void init(int row, int column) {//初始矩陣大小
        n = row, m = column;
    }
 
    void init_e() {//初始化爲單位矩陣
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                mat[i][j] = (i == j);
            }
        }
    }
 
    void print() {//測試檢查用
        puts("——————————————");
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                printf("%d ", (int)mat[i][j]);
            }puts("");
        }puts("");
    }
 
};
 
//加法 重載運算符 +
Matrix operator + (Matrix a, Matrix b) {
    Matrix ret;
    ret.init(a.n, a.m);
    for (int i = 0; i < a.n; i++) {
        for (int j = 0; j < a.m; j++) {
            ret.mat[i][j] = a.mat[i][j] + b.mat[i][j];
            if (ret.mat[i][j] >= mod) {                    //這裏的mod,沒必要時要刪除
                ret.mat[i][j] %= mod;
            }
        }
    }
    return ret;
}//加法
 
//n行m列  *  m行p列   =  n行p列 重載運算符 *
Matrix operator * (Matrix a, Matrix b) {
    Matrix ret;
    ret.init(a.n, b.m);
    for (int i = 0; i < a.n; i++) {
        for (int k = 0; k < a.m; k++) if (a.mat[i][k]) {
            for (int j = 0; j < b.m; j++) if (b.mat[k][j]) {
                ret.mat[i][j] = ret.mat[i][j] + a.mat[i][k] * b.mat[k][j];
                if (ret.mat[i][j] >= mod) {
                    ret.mat[i][j] %= mod;
                }//if
            }//for(j)
        }//for(k)
    }//for(i)
    return ret;
}//乘法
 
//求冪一般都是正方形矩陣,所以ret = a; 重載運算符 ^
Matrix operator ^ (Matrix a, int b) {
    Matrix ret = a,  tmp = a;
    ret.init_e();
    for ( ; b; b >>= 1) {
        if (b & 1) {
            ret = ret * tmp;
        }
        tmp = tmp * tmp;
    }
    return ret;
}//
 
//遞歸冪求和
//用二分法求矩陣和,遞歸實現,一般用下一種非遞歸版
Matrix Power_Sum1(Matrix a, int b) {
    Matrix ret = a;
    ret.init_e();
    if (b == 1) {
        return a;
    } else if (b & 1) {
        return (a ^ b) + Power_Sum1(a, b - 1);
    } else {
        return Power_Sum1(a, b >> 1) * ((a ^ (b >> 1)) + ret);
    }
}//Power_Sum1
 
//非遞歸冪求和
Matrix Power_Sum2(Matrix a, int b) {
    int k = 0 ,ss[32];
    Matrix tp1, tp2, ret;
    tp1 = tp2 = ret = a;
    ret.init_e();
    while (b) {
        ss[k++] = b & 1;
        b >>= 1;
    }
    for (int i = k - 2; i >= 0; i--) {
        tp1 = tp1 * (tp2 + ret);
        tp2 = tp2 * tp2;
        if (ss[i]) {
            tp2 = tp2 * a;
            tp1 = tp1 + tp2;
        }
    }
    return tp1;
}//Power_Sum2
 
int main()
{
    mod=10000;
    int M,cas=1;
    Matrix t0;
    t0.init(6,1);
    t0.mat[0][0]=2;
    for(int i=1;i<6;i++) t0.mat[i][0]=0;
    while(scanf("%d",&M)==1) {
        Matrix t;
        t.init(6,6);
        t.mat[0][0]=t.mat[0][4]=t.mat[0][5]=0;
        t.mat[0][1]=3; t.mat[0][2]=2; t.mat[0][3]=1;
        for(int i=1;i<6;i++) {
            for(int j=0;j<6;j++) t.mat[i][j]=(j==(i-1));
        }
        //t.print();
        if(M==0) {
            printf("Case %d: %d\n",cas++,(2%mod));
            continue;
        }
        t=t^M;
        Matrix ans=t0;
        ans=t*ans;
        LL sum=0;
        for(int i=0;i<6;i++) sum=(sum+ans.mat[i][0])%mod;
        printf("Case %d: %lld\n",cas++,sum);
    }
    return 0;
}
 
/**************************************************************
    Problem: 1313
    User: Roney
    Language: C++
    Result: Accepted
    Time:400 ms
    Memory:1484 kb
****************************************************************/



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章