智能硬件行业资讯,IoT、机器人、AR/VR、智能家居前沿

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

c++信奥二维数组矩阵方面题解 - 图片1

c++信奥二维数组矩阵方面题解 - 图片2

c++信奥二维数组矩阵方面题解 - 图片3

以下是二维数组中常见位置判断条件的整理,假设矩阵大小为 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) 上三角(ij) * * * * * * . . . . . * * * * . . . . . . * * * * * * . . . . . * * * * . . . . . . * * * * * * . . . . . * * * * . . . . . . * * * * * * . . . . . * * * * . . . . . . * * * * * * . . . . . * * * * . 矩阵边界 // 第一行 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 && i0 && j 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 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 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 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 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 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 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 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°旋转就是"上下翻转+左右翻转"。