矩阵

矩阵
顾名思义就是一个小破方阵
类似这样

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;
}

这就是最基本的矩阵了

对于矩阵更重要的作用是[[矩阵快速幂]]

posted @ 2024-04-28 19:41  blind5883  阅读(16)  评论(0编辑  收藏  举报