跳转至

矩阵运算

矩阵,是把一些数按行、列排列成的长方形数表。

例如,一个 2 行 3 列的矩阵:

\[ \begin{pmatrix} 1 & 2 & 3 \\ 4 & 5 & 6 \end{pmatrix} \]

横着是行,竖着是列,每个数叫作元素。n 行 m 列,称为 \(n \times m\) 矩阵。

矩阵可以用二维数组存。先看行列数,再看每个位置怎么处理。

我们下标从 1 开始。 用 a[1][1] 到 a[n][m],第 0 行、第 0 列不用。

数组已读入,行列数为 1~100;a、b 用 int,c 用 long long。

int a[110][110], b[110][110];
long long c[110][110];

数组开在全局,数据和计算结果不能超出类型范围。

矩阵加法

两个矩阵行数相同、列数相同,对应位置相加。

for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
        c[i][j] = 1LL * a[i][j] + b[i][j];
    }
}

1LL 是 long long 类型的 1,让后面的乘法、加法按 long long 计算。

矩阵乘法

前一个矩阵的列数,要等于后一个矩阵的行数。 n × m 乘 m × k,结果是 n × k。

a 的一行与 b 的一列,对应元素相乘,再求和。

for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= k; j++) {
        c[i][j] = 0;
        for (int p = 1; p <= m; p++) {
            c[i][j] += 1LL * a[i][p] * b[p][j];
        }
    }
}

比如 c[1][2]:a 的第 1 行与 b 的第 2 列,对应元素相乘,再求和。

每个 c[i][j],先清零,再累加。 避免加上原来的值。

对角线问题

行数、列数相同的矩阵叫作方阵。这里用 n × n 的方阵。

主对角线:左上到右下,i == j。

for (int i = 1; i <= n; i++) {
    cout << a[i][i] << ' ';
}

副对角线:左下到右上,i + j == n + 1。

for (int i = n; i >= 1; i--) {
    cout << a[i][n + 1 - i] << ' ';
}

下标从 0 开始时,副对角线是 i + j == n - 1,别混用。

同行、同列、同斜线

给定位置 (x, y),x 是行号,y 是列号,不能越界。

同行:固定行号 x,枚举列。

for (int j = 1; j <= m; j++) {
    cout << a[x][j] << ' ';
}

同列:固定列号 y,枚举行。

for (int i = 1; i <= n; i++) {
    cout << a[i][y] << ' ';
}

左上到右下的斜线:行号减列号相同。

for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
        if (i - j == x - y) {
            cout << a[i][j] << ' ';
        }
    }
}

左下到右上的斜线:行号加列号相同。

for (int i = n; i >= 1; i--) {
    for (int j = 1; j <= m; j++) {
        if (i + j == x + y) {
            cout << a[i][j] << ' ';
        }
    }
}

主、副对角线只是其中两条斜线。左上到右下是主对角线,左下到右上是副对角线。