数组操作进阶实战:从矩阵运算到螺旋填充
计算特定区域的矩阵元素和
题目要求对一个n×n方阵,求除副对角线、最后一行和最后一列之外所有元素的总和。副对角线是从右上到左下的连线。
解决思路是先累加全部元素,再减去不需要的部分。通过判断行列索引是否满足 i + j == n - 1(副对角线)、i == n - 1(末行)或 j == n - 1(末列)来排除这些位置。
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int matrix[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &matrix[i][j]);
}
}
int total = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
total += matrix[i][j];
if (i + j == n - 1 || i == n - 1 || j == n - 1) {
total -= matrix[i][j];
}
}
}
printf("%d", total);
return 0;
}
二维数组的循环右移变换
将每个行中的元素整体向右移动m位,超出边界时从左侧重新进入。使用辅助数组避免覆盖原始数据。
关键在于目标列索引为 (j + m) % n,确保移动后正确回绕。
#include <stdio.h>
int main() {
int shift, size;
scanf("%d %d", &shift, &size);
int src[size][size], dst[size][size];
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
scanf("%d", &src[i][j]);
dst[i][j] = src[i][j]; // 初始化
}
}
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
dst[i][(j + shift) % size] = src[i][j];
}
}
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", dst[i][j]);
}
printf("\n");
}
return 0;
}
构建顺时针螺旋填充的方阵
实现一个N×N矩阵,按顺时针方向从外层向内层依次填入1到N²的整数。
采用"四边推进"策略:上行→右列→下行→左列,每完成一边就缩小边界范围,直到填满为止。
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int grid[n][n];
int value = 1;
int top = 0, bottom = n - 1, left = 0, right = n - 1;
while (value <= n * n) {
// 从左到右填充顶行
for (int col = left; col <= right; col++) {
grid[top][col] = value++;
}
top++;
// 从上到下填充右列
for (int row = top; row <= bottom; row++) {
grid[row][right] = value++;
}
right--;
// 从右到左填充底行
for (int col = right; col >= left; col--) {
grid[bottom][col] = value++;
}
bottom--;
// 从下到上填充左列
for (int row = bottom; row >= top; row--) {
grid[row][left] = value++;
}
left++;
}
// 输出格式化结果
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
printf("%3d", grid[i][j]);
}
printf("\n");
}
return 0;
}
生成杨辉三角的前N行
利用动态规划思想构造杨辉三角:每行首尾为1,其余元素等于上一行对应位置与其前一位置之和。
#include <stdio.h>
int main() {
int rows;
scanf("%d", &rows);
int triangle[rows][rows];
for (int i = 0; i < rows; i++) {
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i) {
triangle[i][j] = 1;
} else {
triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j];
}
printf("%7d", triangle[i][j]);
}
printf("\n");
}
return 0;
}
矩阵主对角线与反对角线求和
分别计算正对角线(i == j)和反对角线(i + j == n - 1)上的元素总和。
可在输入时同步处理,减少重复遍历开销。
#include <stdio.h>
int main() {
int n;
scanf("%d", &n);
int mat[n][n];
int diagSum = 0, antiDiagSum = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
scanf("%d", &mat[i][j]);
if (i == j) diagSum += mat[i][j];
if (i + j == n - 1) antiDiagSum += mat[i][j];
}
}
printf("%d %d", diagSum, antiDiagSum);
return 0;
}
查找矩阵中的最小值及其位置
遍历整个M×N矩阵,记录最小值及其坐标。注意题目中行列编号从1开始计数。
#include <stdio.h>
int main() {
int height, width;
scanf("%d %d", &height, &width);
int data[height][width];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
scanf("%d", &data[i][j]);
}
}
int minValue = data[0][0];
int minRow = 0, minCol = 0;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
if (data[i][j] < minValue) {
minValue = data[i][j];
minRow = i;
minCol = j;
}
}
}
printf("%d %d %d", minValue, minRow + 1, minCol + 1);
return 0;
}