問題描述:給出一個n*n的矩陣和正整數k,請求出S=A+A^2+A^3+A^4+...+A^k的值.A^x表示x個A相乘的結果.
關於輸入:輸入包含一組資料.
第一行是三個正整數n k m, (n<=30,k<=1000000000,m<=10000).
接下來n行,每行n個數,表示這個矩陣.
關於輸出:輸出矩陣S對m模數後的值,包括n行,每行n個數
例子輸入:
2 2 4
0 1
1 1
例子輸出:
1 2
2 3
解題思路:令 B= [
[A A]
[0 I]
]
則 B^k = [
[A^k A ... A^k]
[0 I ]
]
則矩陣B的k次方的有上角即為答案。
代碼:
#include <iostream>#define MAX_SIZE 30using namespace std;int n, k, m;/*=====================================================定義矩陣結構MATRIX;並重載操作符+和*.=====================================================*/struct MATRIX{int val[MAX_SIZE][MAX_SIZE];MATRIX operator+(const MATRIX&l){MATRIX temp;for(int i=0; i<n; i++)for(int j=0; j<n; j++)temp.val[i][j]=(val[i][j]+l.val[i][j])%m;return temp;}MATRIX operator*(const MATRIX&l){MATRIX temp;for(int i=0; i<n; i++){for(int j=0; j<n; j++){temp.val[i][j] = 0;for(int k=0; k<n; k++)temp.val[i][j] = (temp.val[i][j] + val[i][k]*l.val[k][j]) % m;}}return temp;}}A,S;/*=====================================================用分治法矩陣的k次方;l為輸入矩陣;k為所求的K次方.=====================================================*/MATRIX power(MATRIX l, int k){MATRIX temp;if(k==1) return l;temp = l*l;if(k&1) return power(temp,(k-1)/2)*l;else return power(temp,k/2);}/*=====================================================用分治法求和;l為輸入矩陣;k為所求的K次方=====================================================*/MATRIX sum(int k){MATRIX temp, tpow; if(k==1)return A; temp=sum(k/2); if(k&1){tpow = power(A,k/2+1);temp = temp + temp*tpow + tpow;} else{temp = temp + power(A,k/2)*temp;} return temp;}int main(){//輸入數組A的參數scanf("%d%d%d",&n,&k,&m);//用於計算的幾個中間變數及矩陣for(int i=0; i<n; i++){for(int j=0; j<n; j++){scanf("%d",&A.val[i][j]);}}//計算矩陣平方和S = sum(k);//輸出數組元素for(int i=0; i<n; i++){for(int j=0; j<n-1; j++){printf("%d ",S.val[i][j]);}printf("%d/n", S.val[i][n-1]);}system("pause");return 0;}