矩阵
在这里插入图片描述
以下是二维数组中常见位置判断条件的整理,假设矩阵大小为 n×n,行列索引从 0 开始:


两条对角线

// 主对角线(左上→右下)
i == j

// 副对角线(右上→左下)
i + j == n - 1

// 两条对角线同时判断
i == j || i + j == n - 1

💡 当 n 为奇数时,两条对角线在中心点 (n/2, n/2) 相交,该元素只会被加一次(用 || 天然去重)。


上三角与下三角

// 上三角(含主对角线):i <= j
// 下三角(含主对角线):i >= j

// 上三角(不含主对角线):i < j
// 下三角(不含主对角线):i > j

用图来理解(n=5,* 表示满足条件的位置):

上三角(i<=j)          下三角(i>=j)          上三角(i<j)          下三角(i>j)
* * * * *            * . . . .            . * * * *            . . . . .
. * * * *            * * . . .            . . * * *            * . . . .
. . * * *            * * * . .            . . . * *            * * . . .
. . . * *            * * * * .            . . . . *            * * * . .
. . . . *            * * * * *            . . . . .            * * * * .

矩阵边界

// 第一行
i == 0

// 最后一行
i == n - 1

// 第一列
j == 0

// 最后一列
j == n - 1

// 四条边(外圈)
i == 0 || i == n - 1 || j == 0 || j == n - 1

常见组合应用

// 只加主对角线,不加副对角线
if(i == j && i + j != n - 1)

// 只加副对角线,不加主对角线
if(i + j == n - 1 && i != j)

// 上三角元素加10
if(i < j)

// 边界元素加10
if(i == 0 || i == n - 1 || j == 0 || j == n - 1)

// 非边界元素(内部元素)
if(i > 0 && i < n - 1 && j > 0 && j < n - 1)

速查表

位置条件
主对角线i == j
副对角线i + j == n - 1
上三角(含对角线)i <= j
下三角(含对角线)i >= j
上三角(不含对角线)i < j
下三角(不含对角线)i > j
四条边i==0 || i==n-1 || j==0 || j==n-1
内部元素i>0 && i<n-1 && j>0 && j<n-1

掌握这些条件后,大部分矩阵位置判断题都可以直接套用了。


题目一:副对角线求和

题目描述:输入一个 n×nn \times nn×n 的矩阵,计算并输出该矩阵副对角线上所有元素的和。
考察重点:副对角线的判断条件 i + j == n - 1。
示例:
输入:
3
1 2 3
4 5 6
7 8 9
输出:15 (因为 3 + 5 + 7 = 15)


题目二:矩阵内圈元素置零

题目描述:输入一个 n×nn \times nn×n 的矩阵(n≥3n \ge 3n≥3),将矩阵最外圈(边界)的元素保持不变,将内部元素全部变为 0,并输出新矩阵。
考察重点:内部元素的判断条件 i > 0 && i < n - 1 && j > 0 && j < n - 1。
示例:
输入:
4
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
输出:
1 1 1 1
2 0 0 2
3 0 0 3
4 4 4 4


题目三:上三角元素翻倍

题目描述:输入一个 n×nn \times nn×n 的矩阵,将矩阵的**上三角区域(包含主对角线)**的所有元素值乘以 2,其余元素保持不变,输出新矩阵。
考察重点:上三角(含对角线)的判断条件 i <= j。
示例:
输入:
3
1 2 3
4 5 6
7 8 9
输出:
2 4 6
4 10 12
7 8 9


题目四:对角线合并与三角区排除

题目描述:输入一个 n×nn \times nn×n 的矩阵,将两条对角线上的元素都加上 10,但不包含主对角线和副对角线交叉的中心点(如果 nnn 为奇数,中心点只加一次,此题要求中心点不加),输出新矩阵。
考察重点:组合条件的运用。主对角线 i == j,副对角线 i + j == n - 1,排除中心点。
示例:
输入:
3
1 1 1
1 1 1
1 1 1
输出:
11 1 11
1 1 1
11 1 11


这几道题的难度刚好覆盖了常见的矩阵位置判断。
以下是四道题的参考代码:


题目一:副对角线求和

#include <iostream>
using namespace std;

int main() {
    int n, sum = 0;
    cin >> n;
    int arr[25][25];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> arr[i][j];

    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (i + j == n - 1)
                sum += arr[i][j];

    cout << sum << endl;
    return 0;
}

题目二:矩阵内圈元素置零

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int arr[25][25];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> arr[i][j];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i > 0 && i < n - 1 && j > 0 && j < n - 1)
                arr[i][j] = 0;
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

题目三:上三角元素翻倍

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int arr[25][25];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> arr[i][j];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (i <= j)
                arr[i][j] *= 2;
            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

题目四:对角线加10但排除中心点

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int arr[25][25];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> arr[i][j];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            // 在对角线上,且不是中心点
            bool onDiagonal = (i == j) || (i + j == n - 1);
            bool isCenter = (n % 2 == 1) && (i == n / 2) && (j == n / 2);

            if (onDiagonal && !isCenter)
                arr[i][j] += 10;

            cout << arr[i][j] << " ";
        }
        cout << endl;
    }
    return 0;
}

各题核心逻辑对照

题目核心条件
题一i + j == n - 1
题二i > 0 && i < n-1 && j > 0 && j < n-1
题三i <= j
题四(i == j || i + j == n-1) && !isCenter

下面给出几道进阶矩阵题及其参考代码:


题目一:矩阵顺时针旋转90度

题目描述:输入一个 n×nn \times nn×n 的矩阵,将其顺时针旋转90度后输出。

思路:先沿主对角线翻转(转置),再左右翻转每行。

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int arr[25][25];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> arr[i][j];

    // 第一步:转置(沿主对角线翻转)
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            swap(arr[i][j], arr[j][i]);

    // 第二步:每行左右翻转
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n / 2; j++)
            swap(arr[i][j], arr[i][n - 1 - j]);

    // 输出
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++)
            cout << arr[i][j] << " ";
        cout << endl;
    }
    return 0;
}

示例:
输入:

3
1 2 3
4 5 6
7 8 9

输出:

7 4 1
8 5 2
9 6 3

题目二:螺旋遍历矩阵

题目描述:输入一个 n×nn \times nn×n 的矩阵,按顺时针螺旋顺序输出所有元素。

思路:设定上下左右四个边界,依次遍历上边→右边→下边→左边,每遍历完一条边就收缩对应边界。

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int arr[25][25];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> arr[i][j];

    int top = 0, bottom = n - 1, left = 0, right = n - 1;

    while (top <= bottom && left <= right) {
        // 上边:从左到右
        for (int j = left; j <= right; j++)
            cout << arr[top][j] << " ";
        top++;

        // 右边:从上到下
        for (int i = top; i <= bottom; i++)
            cout << arr[i][right] << " ";
        right--;

        // 下边:从右到左
        if (top <= bottom) {
            for (int j = right; j >= left; j--)
                cout << arr[bottom][j] << " ";
            bottom--;
        }

        // 左边:从下到上
        if (left <= right) {
            for (int i = bottom; i >= top; i--)
                cout << arr[i][left] << " ";
            left++;
        }
    }
    cout << endl;
    return 0;
}

示例:
输入:

3
1 2 3
4 5 6
7 8 9

输出:

1 2 3 6 9 8 7 4 5

题目三:矩阵转置

题目描述:输入一个 n×nn \times nn×n 的矩阵,输出它的转置矩阵(行列互换)。

思路:沿主对角线交换 arr[i][j] 和 arr[j][i]。

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    int arr[25][25];
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            cin >> arr[i][j];

    // 沿主对角线翻转
    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            swap(arr[i][j], arr[j][i]);

    // 输出
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++)
            cout << arr[i][j] << " ";
        cout << endl;
    }
    return 0;
}

示例:
输入:

3
1 2 3
4 5 6
7 8 9

输出:

1 4 7
2 5 8
3 6 9

各题核心技巧对照

题目核心技巧
顺时针旋转90°转置 + 每行左右翻转
螺旋遍历四个边界变量 top/bottom/left/right 逐步收缩
矩阵转置沿主对角线交换 arr[i][j] 与 arr[j][i]

💡 小贴士:旋转90°的本质是"转置+翻转",记住这个套路后,逆时针旋转90°就是"转置+上下翻转",180°旋转就是"上下翻转+左右翻转"。


更多推荐