矩陣
顧名思義就是一個小破方陣
類似這樣
0 0 1 1
0 1 0 1
0 1 1 1
0 0 0 0
這就是一個四行四列的矩陣,
矩陣包含三個資訊, 長度, 寬度, 數值
數值就是矩陣裡每一位上的數值, 通常用一個數值來存
為了方便使用我們常寫成結構體形式
定義
struct Mat
{
int l, r; // 長, 寬
int a[N][N]; // 矩陣陣列
};
那麼矩陣有什麼作用呢?
在定義中, 矩陣滿足加, 減, 乘三種運算
矩陣加減
兩個矩陣A, B可以加減的前提是他們的長寬對應相等
如下
A
1 2 3
4 5 6
7 8 9
3 4 2
B
5 3 3
4 5 8
9 9 9
7 7 7
這兩個矩陣長寬相等於是可以加減
而矩陣加減非常簡單, 就是對應位置加減, 就和普通運算一樣, 具有交換律和結合律
如B - A
4 1 0
0 0 2
2 1 0
4 3 5
可得到如上矩陣
這就是矩陣加減, 因為很簡單, 所以基本不考
程式碼
核心程式碼
struct Mat
{
int l, r;
int a[N][N];
}A, B, C;
Mat Mat_add(Mat &A, Mat &B) // 矩陣減同理
{
Mat temp;
temp = {A.l, A.r};
for (int i = 1; i <= A.l; i ++ )
for (int j = 1; j <= A.r; j ++ )
temp.a[i][j] = A.a[i][j] + B.a[i][j];
return temp;
}
具體程式碼
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100;
int n, m;
struct Mat
{
int l, r;
int a[N][N];
}A, B, C;
Mat Mat_add(Mat &A, Mat &B)
{
Mat temp;
temp = {A.l, A.r};
for (int i = 1; i <= A.l; i ++ )
for (int j = 1; j <= A.r; j ++ )
temp.a[i][j] = A.a[i][j] + B.a[i][j];
return temp;
}
void print(Mat &A)
{
for (int i = 1; i <= A.l; i ++ )
{
for (int j = 1; j <= A.r; j ++ )
printf("%-2d ", A.a[i][j]);
puts("");
}
puts("");
}
int main()
{
cin >> n >> m;
A = {n, m};
B = {n, m};
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
cin >> A.a[i][j];
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= m; j ++ )
cin >> B.a[i][j];
C = Mat_add(A, B);
print(C);
return 0;
}
矩陣乘法
相對於矩陣加減, 矩陣乘法就要重要很多
它的前提是兩個矩陣A * B, A的寬度要等於, B的長度 (長度為上面定義中的l
,寬度為r
)
怎麼乘呢?
設A
1 2 3
4 5 6
B
3 1
4 2
5 8
用A第i行的第k個數去乘, B第j列的第k個數, 得到的這k個結果相加就是新矩陣C的第i行第j列的數值
設i = 1, j = 2
那麼就是
1 2 3
1
2
8
ans = 1 * 1 + 2 * 2 +3 * 8
那麼C.a[i][j] = 1 * 1 + 2 * 2 +3 * 8 = 29
總結一下就是, A矩陣的第i行和B矩陣的第j列對應項相乘之和就是, 結果矩陣C的第i行第j列的結果
同時結果矩陣C的長度為A的長度, 寬度為B的寬度
那麼A * B的結果矩陣C就是
26 29
48 62
剛開始學矩陣會很陌生, 但是不要緊, 多算算就熟練了
性質
因為其這個i行j列相乘的性質, 所以矩陣乘法是沒有交換律的
你現在可以試試求求B * A 看看是否滿足 B * A == A * B
雖然沒有交換律, 但是它具有結合律, 也就是(A * B) * C == A * (B * C)
自己也可以試試, 這裡不證明了
程式碼
看看程式碼吧
Mat Mat_mul(Mat &A, Mat &B, int p) // A * B 每一項取模 p, 返回結果矩陣
{
Mat temp = {A.l, B.r}; // 我們一般開一個矩陣存結果, 並在最後返回它
// 下面就是正常的計算, 請自行理解, 這裡沒法言傳
for (int i = 1; i <= A.l; i ++ )
for (int j = 1; j <= B.r; j ++ )
for (int k = 1; k <= A.r; k ++ ) // A.r == B.l
temp.a[i][j] = (temp.a[i][j] + 1ll * A.a[i][k] * B.a[k][j]) % p;
// 記得防爆int
return temp;
}
這就是最基本的矩陣了
對於矩陣更重要的作用是[[矩陣快速冪]]