TOJ 3848 Game 矩阵快速幂

来源:互联网 发布:优化数据库的方法 编辑:程序博客网 时间:2024/06/08 03:33

Perhaps there is three people:

                                                            1    2    3

(S1,S2,S3) = (S1,S2,S3)( 2    1    2)^ N

                                                             0    3    1

The first column is s1 vs s1, s1 vs s2,s1 vs s3;

The scond column is s2 vs s1 ,s2 vs s2 ,s2 vs s3;

The third column is s3 vs s1 ,s3 vs s2 ,s3 vs s3;

The portal:http://acm.tju.edu.cn/toj/showp3848.html

函数版:

//TOJ 3849#include <cstdio>#include <cstring>#include <cstdlib>int Len_Matrix;int Mod;struct Matrix {    int M[55][55];};void Init_Matrix(Matrix & tmp) {    for(int i = 1 ; i <= Len_Matrix ; i++) {        for(int j = 1 ; j <= Len_Matrix ; j++) {            if(i == j)tmp.M[i][j] = 1;            else tmp.M[i][j] = 0;        }    }}void Debug(Matrix tmp) {    for(int i = 1 ; i <= Len_Matrix ; i ++) {        for(int j = 1 ; j <= Len_Matrix ; j ++) {            printf("%d ",tmp.M[i][j]);        }        puts("");    }    puts("");}Matrix Multiply(Matrix a1,Matrix a2) {    Matrix ans ;    Init_Matrix(ans);    for(int i = 1 ; i <= Len_Matrix ; i++) {        for(int j = 1 ; j <= Len_Matrix ; j++) {            int temp_ans  = 0;            for(int k = 1 ; k <= Len_Matrix ; k++) {                temp_ans = (temp_ans + a1.M[i][k] * a2.M[k][j])%Mod;             }            ans.M[i][j] = temp_ans;        }    }    return ans;}Matrix Pow(Matrix a1,int n) {    Matrix ans ;    Init_Matrix(ans);    while(n) {        if(n&1) ans = Multiply(ans,a1);        a1 = Multiply(a1,a1);        n >>= 1;    }    return ans;}void Deal_with() {    int T;    scanf("%d",&T);    while(T--) {        int M,P,N;        scanf("%d %d %d",&M,&P,&N);        Matrix tmp;        Matrix ss;        Mod = P;        Len_Matrix = M;        int id,init_value,K,d_id,d_times;        Init_Matrix(tmp);        for(int i = 1 ; i <= M ; i++ ) {            scanf("%d %d %d",&id,&init_value,&K);            ss.M[1][id] = init_value;            for(int j = 1 ; j <=  K ; j ++) {                scanf("%d %d",&d_id,&d_times);                tmp.M[d_id][id] = d_times;            }        }        for(int i = 2 ; i <= M ; i++ ) {            for(int j = 1 ; j <= M ; j++){                ss.M[i][j] = 0;            }        }        Matrix ans;        ans = Pow(tmp,N);        //Debug(ans);        ans = Multiply(ss,ans);        //Debug(ans);        int max_score = -1;        for(int i = 1 ; i <= M ; i++) {            if(ans.M[1][i] > max_score) max_score = ans.M[1][i];        }        printf("%d\n",max_score);    }}int main(void) {    //freopen("a.in","r",stdin);    Deal_with();    return 0;}

用类的重构版:

#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>int Mod ;class Matrix {public:    int M[55][55];    int Len_Matrix;    Matrix(){memset(M,0,sizeof(M));}    Matrix(int Len_Matrix_) : Len_Matrix(Len_Matrix_) {        memset(M,0,sizeof(M));        for(int i = 1 ; i <= Len_Matrix ; i++ ) {            M[i][i]  = 1;        }    }    Matrix operator * (const Matrix a) const {        Matrix b;        b.Len_Matrix = Len_Matrix;        for(int i = 1 ; i <= Len_Matrix ; i ++) {            for(int j = 1 ; j <= Len_Matrix ; j++) {                for(int k = 1 ; k <= Len_Matrix ; k++) {                    b.M[i][j] = (b.M[i][j] + M[i][k] * a.M[k][j] ) % Mod;                 }               }        }         return b;    }    Matrix operator ^ (const int n) const {        Matrix ans(Len_Matrix);        Matrix base = * this;        int k = n;        while(k) {            if(k & 1) ans = ans * base;            base = base * base;            k >>= 1;        }        //ans.Debug();        return ans;    }    void Debug() {        printf("Len_Matrix : %d\n",Len_Matrix);        for(int i = 1 ; i <= Len_Matrix ; i++) {            for(int j = 1 ; j <= Len_Matrix ; j++) {                printf("%d ",M[i][j]);            }            puts("");        }        puts("");    }};void Deal_with() {    int T;    scanf("%d",&T);    while(T--) {        int M,P,N;        scanf("%d %d %d",&M,&P,&N);        Mod = P;        Matrix tmp(M);        //tmp.Debug();        Matrix ss;        ss.Len_Matrix = M;        int id,init_value,K,d_id,d_times;        for(int i = 1 ; i <= M ; i++ ) {            scanf("%d %d %d",&id,&init_value,&K);            ss.M[1][id] = init_value;            for(int j = 1 ; j <=  K ; j ++) {                scanf("%d %d",&d_id,&d_times);                tmp.M[d_id][id] = d_times;            }        }        Matrix ans;        //printf("Len_Matrix : %d M : %d\n",ans.Len_Matrix,M);        ans.Len_Matrix = M;        //printf("Len_Matrix : %d M : %d\n",ans.Len_Matrix,M);        //ans.Debug();        ans = tmp ^ N;        //ans.Debug();        ans = ss * ans;        //ans.Debug();        int max_score = -1;        for(int i = 1 ; i <= M ; i++) {            if(ans.M[1][i] > max_score) max_score = ans.M[1][i];        }        printf("%d\n",max_score);    }}int main(void) {    //freopen("a.in","r",stdin);    Deal_with();    return 0;}



0 0