分析:
一. 首先我们了解一下什么是矩阵乘法:
通过观察发现:
乘积C的第1行第1列的元素等于矩阵A的第1行的元素与矩阵B的第1列对应元素乘积之和;
乘积C的第1行第2列的元素等于矩阵A的第1行的元素与矩阵B的第2列对应元素乘积之和;
乘积C的第2行第1列的元素等于矩阵A的第2行的元素与矩阵B的第1列对应元素乘积之和;
乘积C的第2行第2列的元素等于矩阵A的第2行的元素与矩阵B的第2列对应元素乘积之和;
由此推出一般性的规律:
乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和
当然还有一些注意事项:
-
当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。
-
矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。
二. 求矩阵A的M次幂
当M=0时结果为单位矩阵,即正对角线上的值都为1,其他值为0;
当M=1时结果为原来的矩阵;
当M>1时即为M个矩阵A相乘的结果。需要注意的是,读入的M代表矩阵的M次方,也就是矩阵和自己乘M-1次,注意这点,不然很有可能会多乘一次。
总的来说,矩阵计算的算法是:
C(i,j)=A(i,m)*B(m,j) 【 for m = 0 … n】
Java代码实现:
以下代码是错的,为了更好地总结就放上来了~~
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt(); //N阶
int M = scanner.nextInt(); //M次幂
int[][] a = new int[N][N]; //用二维数组a接收矩阵A
int[][] c = new int[N][N]; //二维数组c接收矩阵A,并用于存储结果矩阵
int i,j;
//用二维数组a接收矩阵A
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
a[i][j] = c[i][j]= scanner.nextInt();
}
}
//矩阵乘法
if (M == 0) {
for (i = 0; i < N; i++) {
for(j = 0; j < N; j++) {
if (i == j) {
System.out.print(1 + " ");
} else {
System.out.print(0 + " ");
}
}
System.out.println();
}
} else if (M == 1) {
for (i = 0; i < N; i++) {
for(j = 0; j < N; j++) {
System.out.print(c[i][j] + " ");
}
System.out.println();
}
} else {
for (int m = 1; m < M; m++) { //最外层控制M次幂
for (i = 0; i < N; i++) { //i控制行
for (j = 0; j < N; j++) { //j控制列
int sum = 0;
for (int k = 0; k < N; k++) {
sum += a[i][k] * a[k][j];
}
c[i][j] = sum;
}
}
}
}
//打印结果矩阵C
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
}
目前这个代码还是有bug的,测试用例能够通过,但是提交到OJ之后显示“答案错误71%”,由于看不到测试数据,暂时还找不到原因。
3月9日更新:
今天重新研究了这道题,以下代码通过了。上一段代码是在M>1 的情况下出错了,原因是我对矩阵乘法的理解还不够深入。上一段代码是在M>1 时算出来的结果应该都是2次幂的,原因是我没有将中间过程的结果参与到运算中,相当于只进行了一次运算。
具体区别欢迎读者进行比较,一起交流讨论,若有不足之处欢迎指正。
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int N = scanner.nextInt(); //N阶
int M = scanner.nextInt(); //M次幂
int[][] a = new int[N][N]; //用二维数组a接收矩阵A
int[][] c = new int[N][N]; //二维数组c接收矩阵A,并用于存储结果矩阵
int i,j;
//用二维数组a接收矩阵A
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
a[i][j] = c[i][j]= scanner.nextInt();
}
}
//矩阵乘法
if (M == 0) { //当M=0时结果为单位矩阵
for (i = 0; i < N; i++) {
for(j = 0; j < N; j++) {
if (i == j) {
System.out.print(1 + " ");
} else {
System.out.print(0 + " ");
}
}
System.out.println();
}
} else if (M == 1) { //当M=1时结果为原来的矩阵
for (i = 0; i < N; i++) {
for(j = 0; j < N; j++) {
System.out.print(c[i][j] + " ");
}
System.out.println();
}
} else { //当M>1时即为M个矩阵A相乘的结果。
for (int m = 1; m < M; m++) { //最外层控制M次幂,m从1开始或m<M -1都可以,不要乘多一次
int[][] temp = new int[N][N];
for (i = 0; i < N; i++) { //i控制行
for (j = 0; j < N; j++) { //j控制列
int sum = 0;
for (int k = 0; k < N; k++) {
sum += a[i][k] * c[k][j];
}
temp[i][j] = sum;
}
}
c = temp;
}
//打印结果矩阵C
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
System.out.print(c[i][j] + " ");
}
System.out.println();
}
}
}
}