北邮机试 | bupt oj | 96. 矩阵幂 | 快速幂以及矩阵快速幂详细解答

版权声明:本人小白,有错误之处恳请指出,感激不尽;欢迎转载 https://blog.csdn.net/stone_fall/article/details/88562053

时间限制 1000 ms 内存限制 65536 KB

题目描述

​给你一个n*n的矩阵

求其矩阵的k次幂,即Pk

输入格式

第一行,一个整数T(0<T<=10),表示要求矩阵的个数。

接下来有T组数据,每组数据格式如下:

第一行:两个数据n(2<=n<=10)、k(1<=k<=5),两个数字之间用一个空格隔开,其中n表示状况空间的总数,k表示待求的转移概率矩阵的步数。接下来有n行n列个正整数,其中,第i行第j列表示pij,(0<=pij<=10)。另外,数据保证最后结果不会超过10^8。

输出格式

输出为T组数据。

每组数据为已知矩阵的k次幂,格式为:

n行n列个正整数,每行数之间用空格隔开,注意,每行最后一个数后面不应该有多余的空格。

输入样例

3
2 2
9 8
9 3
3 3
4 8 4
9 3 0
3 5 7
5 2
4 0 3 0 1
0 0 5 8 5
8 9 8 5 3
9 6 1 7 8
7 2 5 7 3

输出样例

153 96
108 81
1216 1248 708
1089 927 504
1161 1151 739
47 29 41 22 16
147 103 73 116 94
162 108 153 168 126
163 67 112 158 122
152 93 93 111 97

 AC代码

 

知识点学习:

来自唐主席的博客!我是唐主席死忠粉!

我给大家加了备注!更方便食用。

下面是唐主席的博客。

https://blog.csdn.net/TQCAI666/article/details/86673441

快速幂

//  a^(n)=a^(n/2)*a^(n/2) 来节省乘法运算次数
ll quickPower(ll a,ll b){
    //底为a,指数为b
    ll ans=1,base=a;
    while(b>0){
        //& 按位与运算 如果指数为奇数,需要乘一次底数
        if(b&1){
            ans*=base;
        }
        base*=base;
        // >> 有符号右移 将运算数的二进制整体右移指定位数,整数高位用0补齐,负数高位用1补齐
        // 此处相当于b = b/2
        b>>=1;
    }
    return ans;
}

比如

a^11  11二进制码为1011。此时 b = 1011(B)

第一轮

b&1=true ans = ans * base = a

base *=base   base = a^2

b = 101(B)

第二轮

b&1 = true ans = ans * base = a^3

base = a^4

b = 10(B)

第三轮

b&1 false

base = a^8

b = 1(B)

第四轮

b&1=true ans = ans*base = a^3 * a^8 = a^11

循环到这里就结束了

矩阵乘法

matrix* multi(matrix& A, matrix& B){
    //创建一个新的矩阵保存计算后的数据
    matrix* C=new matrix;
    //矩阵乘法的运算规则
    C->row=A.row;
    C->col=B.col;
    //矩阵乘法运算
    for(int i=0;i<A.row;i++)
        for(int j=0;j<B.col;j++)
            for(int k=0;k<A.col;k++)
                C->m[i][j]+=A.m[i][k]*B.m[k][j];
    return C;
}

矩阵快速幂

这里就是将上面两个合并得到的

matrix quickPower(matrix& A,int p){    //A^p
    int n=A.col;
    //得到单位阵
    matrix ans(n,n);
    //ans=E
    FF(i,n)
        FF(j,n)
            if(i==j)
                ans.m[i][j]=1;
            else
                ans.m[i][j]=0;
    //开始快速幂
    matrix base=A;
    while(p){
        if(p&1)
            ans=*multi(ans,base);
        base=*multi(base,base);
        p>>=1;
    }
    return ans;
}

猜你喜欢

转载自blog.csdn.net/stone_fall/article/details/88562053