矩阵运算¶
矩阵加法¶
矩阵乘法¶
int a[N][M], b[M][K], c[N][K], n, m, k; // [n ,m] * [m, k]
int main() {
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= k; j++)
            for (int p = 1; p <= m; p++)
                c[i][j] += a[i][p] * b[p][k];
}
对角线问题¶
左上到右下,这条对角线上的点
特征:行等于列,
i == j
左下到右上,这条对角线上的点
特征:
行 + 列 = n + 1
for (int i = n; i >= 1; i--)
    for (int j = 1; j <= n; j++)
        if (i + j == n + 1) cout << a[i][j] << ' ';
同行、同列、同斜线问题¶
同行,就是行号一样。钉住行号,枚举列
同列,就是列号一样。钉住列号,枚举行
同斜线,和
(x, y)同在一条斜线上,从左上到右下遍历
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
        if (x + y == i + j) cout << a[i][j] << ' '; 
同斜线,和
(x, y)同在一条斜线上,从左下到右上遍历
for (int i = n; i >= 1; i--)
    for (int j = 1; j <= n; j++)
        if (y - x == j - i) cout << a[i][j] << ' ';
矩阵转置¶
转置是将原矩阵的行变成列,列变成行。
从[遍历行],转向到[遍历列],改变[遍历顺序],直接输出
cin >> n >> m;
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
        cin >> a[i][j];
for (int j = 1; j <= m; j++) {
    for (int i = 1; i <= n; i++) cout << a[i][j] << ' ';
    cout << endl;
}
枚举移动前的元素,考虑将这些元素移动到什么位置
cin >> n >> m;
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
        cin >> a[i][j];
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++)
        b[j][i] = a[i][j];
枚举移动后的元素,寻找这个位置的元素从哪过来的
向右旋转90°(难点)¶
n * n 的矩阵,向右旋转 90°
// 盯住 a[i][j] 这个位置,看旋转到哪去
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
        b[j][n + 1 - j] = a[i][j];
// 盯住 b[i][j] 这个位置,看从哪旋转过来的
for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++)
        b[i][j] = a[n + 1 - j][i];
同理,向左旋转 90°,也是类似的写法。
矩阵的填充(难点)¶
#include <bits/stdc++.h>
using namespace std;
int a[25][25], n;
int idx;
int main()
{
    cin >> n;
    int i = 1, j = n;
    while (idx < n * n){
        while (i <= n && !a[i][j]) a[i++][j] = ++idx;
        i--, j--;
        while (j >= 1 && !a[i][j]) a[i][j--] = ++idx;
        j++, i--;
        while (i >= 1 && !a[i][j]) a[i--][j] = ++idx;
        i++, j++;
        while (j <= n && !a[i][j]) a[i][j++] = ++idx;
        i++, j--;
    }
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++) cout << a[i][j] << ' ';
        puts("");
    }
    return 0;
}
// 第二种写法
#include<bits/stdc++.h>
using namespace std;
const int N = 25;
int a[N][N], n;
int dx[] = {1, 0, -1, 0}, dy[] = {0, -1, 0, 1};  // delta
int idx = 1;
int main(){
    cin >> n;
    int i = 1, j = n;
    while (idx < n * n){
        for (int k = 0; k < 4; k++){
            while (true){
                a[i][j] = idx++;
                i += dx[k], j += dy[k];
                if (i > n || i < 1 || j > n || j < 1 || a[i][j]){
                    i -= dx[k], j -= dy[k], idx--;
                    break;
                }
            }
        }
    }
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++) cout << a[i][j] << ' ';
        puts("");
    }
    return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 25;
int a[N][N], n;
bool check(int x, int y) {
    return x >= 1 && x <= n && y >= 1 && y <= n;
}
int main() {
    cin >> n;
    int x = 1, y = n, idx = 1;
    int px = 1, py = n;
    while (idx <= n * n) {
        x = px, y = py;
        if (px == 1) py--;
        else px ++;
        if (py < 1) {
            py = 1;
            px++;;
        }
        while (check(x, y)) {
            a[x++][y++] = idx++;
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= n; j++) printf("%4d", a[i][j]);
        puts("");
    }
    return 0;
}
#include <iostream>
using namespace std;
int a[50][50], n;
int main() {
    cin >> n;
    int x = 1, y = n, idx = 1;
    n = 2 * n - 1;
    while (idx <= n * n) {
        a[x][y] = idx++;
        if (x == 1) {
            if (y == n) x++;
            else x = n, y++;
        }
        else if (y == n) y = 1, x--;
        else if (a[x - 1][y + 1]) x++;
        else x--, y++;
    }
    for (int i = 1; i <= n; i++){
        for (int j = 1; j <= n; j++) cout << a[i][j] << ' ';
        puts("");
    }
    return 0;
}