c++信奥二维数组矩阵方面题解


以下是二维数组中常见位置判断条件的整理,假设矩阵大小为 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°旋转就是"上下翻转+左右翻转"。
更多推荐


所有评论(0)