第二节 二维数组
2041:【例5.9】新矩阵
#include <stdio.h>
int main()
{
int n, a[30][30];
// 输入矩阵大小
scanf("%d", &n);
// 输入矩阵元素
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
scanf("%d", &a[i][j]);
}
}
// 对角线数字加10
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
// 左上右下对角线:横纵坐标相同
// 右上左下对角线:横纵坐标相加和为n+1
if(i == j || i+j == n+1)
{
a[i][j] += 10;
}
}
}
// 输出矩阵
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
2042:【例5.10】稀疏矩阵
#include <stdio.h>
int main()
{
int n, m, a[105][105] = {
}; // 数组a初始化为0
scanf("%d%d", &n, &m);
// 输入矩阵元素
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
}
}
// 输出大于0的元素及其位置
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= m; ++j)
{
if(a[i][j] > 0)
{
printf("%d %d %d\n", i, j, a[i][j]);
}
}
}
return 0;
}
2043:【例5.11】杨辉三角形
#include <stdio.h>
int main()
{
int n, a[25][25] = {
}; // 注意:数组要初始化为0,这样让每行最后一个1也能通过递推关系得到
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= i; ++j) // 每行有i个元素
{
if(j == 1)
a[i][j] = 1; // 递推初始状态
else
a[i][j] = a[i-1][j] + a[i-1][j-1]; // 递推关系
}
}
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= i; ++j) // 每行有i个元素
printf("%d ", a[i][j]);
printf("\n");
}
return 0;
}
2044:【例5.12】回文字串
#include <stdio.h>
#include <string.h>
int main()
{
char s[105];
scanf("%s", s);
int len = strlen(s) - 1; // 去掉最后的'.'
for(int i = 0; i < len/2; ++i) // 遍历一半字符串
{
if(s[i] != s[len-i-1])
{
// 存在不对应的字符,不是回文串
printf("No");
return 0;
}
}
printf("Yes");
return 0;
}
2045:【例5.13】蛇形填数
#include <stdio.h>
int main()
{
int dir[4][2] = {
{
1, 0}, {
0, -1}, {
-1, 0}, {
0, 1}}; // 方向数组
int a[25][25] = {
}, k = 1, n, fx, fy, d = 0, x, y; // fx, fy当前焦点位置 x,y下一个位置 d:方向
scanf("%d", &n);
fx = 1, fy = n;
while(k <= n*n)
{
a[fx][fy] = k++; // 赋值
x = fx + dir[d][0], y = fy + dir[d][1]; // 下一个位置
if(a[x][y] != 0 || x > n || x < 1 || y > n || y < 1) // 如果新位置上已经有值了或移出了二维数组范围
d = (d + 1) % 4; // 变换方向
fx += dir[d][0], fy += dir[d][1]; // 更新焦点位置
}
for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= n; ++j)
printf("%d ", a[i][j]);
printf("\n");
}
return 0;
}
1119:矩阵交换行
#include <stdio.h>
int main()
{
int a[6][6], m, n;
// 输入矩阵
for(int i = 1; i <= 5; ++i)
{
for(int j = 1; j <= 5; ++j)
{
scanf("%d", &a[i][j]);
}
}
scanf("%d %d", &m, &n); // 输入m和n
// 交换第m行与第n行
for(int j = 1; j <= 5; ++j)
{
int temp = a[m][j];
a[m][j] = a[n][j];
a[n][j] = temp;
}
// 输出矩阵
for(int i = 1; i <= 5; ++i)
{
for(int j = 1; j <= 5; ++j)
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
1120:同行列对角线的格
#include <stdio.h>
int main()
{
int n, sx, sy, x, y, a[15][15]; // 声明变量
scanf("%d %d %d", &n, &sx, &sy); // 输入n、sx和sy
// 输出同一行的格子
for(int j = 1; j <= n; ++j)
{
printf("(%d,%d) ", sx, j);
}
putchar('\n'); // 换行
// 输出同一列上的格子
for(int i = 1; i <= n; ++i)
{
printf("(%d,%d) ", i, sy);
}
putchar('\n'); // 换行
x = sx, y = sy; // 初始化焦点位置
// 寻找与(sx,sy)在同一左上右下斜线上,左上方的第一个位置
while(x > 1 && y > 1)
{
x--, y--; // 向左上方移动
}
// 输出左上右下斜线上的格子
for(; x <= n && y <= n; ++x, ++y)
{
printf("(%d,%d) ", x, y);
}
putchar('\n'); // 换行
x = sx, y = sy; // 重新初始化焦点位置
// 寻找与(sx,sy)在同一左下右上斜线上,左下方的第一个位置
while(x < n && y > 1)
{
x++, y--; // 向左下方移动
}
// 输出左下右上斜线上的格子
for(; x >= 1 && y <= n; --x, ++y)
{
printf("(%d,%d) ", x, y);
}
return 0;
}
1121:计算矩阵边缘元素之和
#include <stdio.h>
int main()
{
int a[101][101], m, n, sum = 0; // 声明变量,m行n列
scanf("%d %d", &m, &n); // 输入m和n
for(int i = 1; i <= m; ++i)
{
for(int j = 1; j <= n; ++j)
{
scanf("%d", &a[i][j]); // 输入矩阵元素
}
}
for(int i = 1; i <= m; ++i) // 第1列和第n列加和
{
sum += a[i][1];
if(n != 1) // 如果矩阵不是只有1列
{
sum += a[i][n];
}
}
for(int j = 2; j <= n - 1; ++j) // 第1行和第m行,除去两端元素后,加和
{
sum += a[1][j];
if(m != 1) // 如果矩阵不是只有1行
{
sum += a[m][j];
}
}
printf("%d", sum);
return 0;
}
1122:计算鞍点
#include <stdio.h>
#include <stdbool.h>
int main()
{
int a[6][6];
for(int i = 1; i <= 5; ++i)
{
for(int j = 1; j <= 5; ++j)
{
scanf("%d", &a[i][j]); // 输入矩阵元素
}
}
bool isFound = false; // 是否找到鞍点
for(int i = 1; i <= 5; ++i) // 遍历每一行
{
int m_j = 1; // m_j: 最大值的纵坐标
for(int j = 1; j <= 5; ++j) // 遍历第i行,j是列号,找到最大值
{
if(a[i][j] > a[i][m_j])
m_j = j;
}
// 此时a[i][m_j]是第i行的最大值
bool isAndian = true; // 判断a[i][m_j]是否是第m_j列的最小值,如果是,那么a[i][m_j]就是鞍点
for(int k = 1; k <= 5; ++k) // 遍历第m_j列 k是行号
{
if(a[k][m_j] < a[i][m_j]) // 只要在第m_j列找到一个小于a[i][m_j]的元素,那么该点就不是鞍点
{
isAndian = false;
break;
}
}
if(isAndian)
{
printf("%d %d %d\n", i, m_j, a[i][m_j]);
isFound = true;
break;
}
}
if(isFound == false)
printf("not found\n");
return 0;
}
1122:计算鞍点
#include <stdio.h>
int main()
{
int isFound = 0; // 是否找到鞍点,0表示未找到,1表示找到
int a[6][6];
for(int i = 1; i <= 5; ++i)
{
for(int j = 1; j <= 5; ++j)
{
scanf("%d", &a[i][j]); // 输入矩阵元素
}
}
for(int i = 1; i <= 5; ++i) // 遍历每一行
{
int m_j = 1; // m_j: 最大值的纵坐标
for(int j = 1; j <= 5; ++j) // 遍历第i行,j是列号,找到最大值
{
if(a[i][j] > a[i][m_j])
m_j = j;
}
// 此时a[i][m_j]是第i行的最大值
int isAndian = 1; // 判断a[i][m_j]是否是第m_j列的最小值,如果是,那么a[i][m_j]就是鞍点,1表示是,0表示否
for(int k = 1; k <= 5; ++k) // 遍历第m_j列 k是行号
{
if(a[k][m_j] < a[i][m_j]) // 只要在第m_j列找到一个小于a[i][m_j]的元素,那么该点就不是鞍点
{
isAndian = 0;
break;
}
}
if(isAndian)
{
printf("%d %d %d\n", i, m_j, a[i][m_j]);
isFound = 1;
break;
}
}
if(isFound == 0)
printf("not found\n");
return 0;
}
1123:图像相似度
#include <stdio.h>
int main()
{
int m, n, s = 0, a[100][100], b[100][100]; // m: 行数, n: 列数, s: 相同像素点个数
scanf("%d %d", &m, &n); // 输入行数和列数
for(int i = 0; i < m; ++i) // 输入二维数组a
{
for(int j = 0; j < n; ++j)
{
scanf("%d", &a[i][j]);
}
}
for(int i = 0; i < m; ++i) // 输入二维数组b
{
for(int j = 0; j < n; ++j)
{
scanf("%d", &b[i][j]);
}
}
for(int i = 0; i < m; ++i) // 遍历二维数组每个位置,判断是否相等
{
for(int j = 0; j < n; ++j)
{
if(a[i][j] == b[i][j])
{
s++;
}
}
}
printf("%.2lf", (double)s/(m*n)*100); // 输出相同像素点的百分比,保留两位小数
return 0;
}
1124:矩阵加法
#include <stdio.h>
#define N 105
int main()
{
int m, n, a[N][N], b[N][N], r[N][N]; // m: 列数, n: 行数
scanf("%d %d", &n, &m); // 输入行数和列数
for(int i = 1; i <= n; ++i) // 输入二维数组a
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= n; ++i) // 输入二维数组b
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &b[i][j]);
}
}
for(int i = 1; i <= n; ++i) // 计算r数组的每个元素
{
for(int j = 1; j <= m; ++j)
{
r[i][j] = a[i][j] + b[i][j];
}
}
for(int i = 1; i <= n; ++i) // 输出r数组
{
for(int j = 1; j <= m; ++j)
{
printf("%d ", r[i][j]);
}
printf("\n");
}
return 0;
}
1125:矩阵乘法
#include <stdio.h>
#define N 105
int main()
{
int m, n, k, a[N][N], b[N][N], r[N][N] = {
0}; // r初始化为0
scanf("%d %d %d", &n, &m, &k); // 输入n、m和k
for(int i = 1; i <= n; ++i) // 输入n*m矩阵a
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= m; ++i) // 输入m*k矩阵b
{
for(int j = 1; j <= k; ++j)
{
scanf("%d", &b[i][j]);
}
}
for(int i = 1; i <= n; ++i) // 结果矩阵r为n行k列,求r每一个元素的值
{
for(int j = 1; j <= k; ++j)
{
for(int x = 1; x <= m; ++x) // 公式:r[i][j] = a[i][1]*b[1][j] + a[i][2]*b[2][j] + ... + a[i][m] * b[m][j]
{
r[i][j] += a[i][x] * b[x][j];
}
}
}
for(int i = 1; i <= n; ++i) // 输出结果矩阵r
{
for(int j = 1; j <= k; ++j)
{
printf("%d ", r[i][j]);
}
printf("\n");
}
return 0;
}
1126:矩阵转置
#include <stdio.h>
#define N 105
int main()
{
int m, n, a[N][N], r[N][N];
scanf("%d %d", &n, &m); // 输入n和m
for(int i = 1; i <= n; ++i) // 输入n*m矩阵a
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= n; ++i) // 转置矩阵
{
for(int j = 1; j <= m; ++j)
{
r[j][i] = a[i][j];
}
}
for(int i = 1; i <= m; ++i) // 输出转置后的矩阵r
{
for(int j = 1; j <= n; ++j)
{
printf("%d ", r[i][j]);
}
printf("\n");
}
return 0;
}
1127:图像旋转
#include <stdio.h>
#define N 105
int main()
{
int n, m, a[N][N], b[N][N];
scanf("%d %d", &n, &m); // 输入n和m
for(int i = 1; i <= n; ++i) // 输入n*m矩阵a
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= n; ++i) // 转置矩阵
{
for(int j = 1; j <= m; ++j)
{
b[j][n - i + 1] = a[i][j];
}
}
for(int i = 1; i <= m; ++i) // 输出转置后的矩阵b
{
for(int j = 1; j <= n; ++j)
{
printf("%d ", b[i][j]);
}
printf("\n");
}
return 0;
}
1128:图像模糊处理
#include <stdio.h>
#include <math.h>
#define N 105
int main()
{
int n, m, a[N][N], b[N][N];
scanf("%d %d", &n, &m); // 输入n和m
for(int i = 1; i <= n; ++i) // 输入矩阵a
{
for(int j = 1; j <= m; ++j)
{
scanf("%d", &a[i][j]);
}
}
for(int i = 1; i <= n; ++i) // 处理矩阵b
{
for(int j = 1; j <= m; ++j)
{
if(i == 1 || i == n || j == 1 || j == m) // 如果是四边,灰度值不变
{
b[i][j] = a[i][j];
}
else // 中心的位置灰度值是上下左右中数字的平均
{
b[i][j] = round((double)(a[i-1][j] + a[i+1][j] + a[i][j-1] + a[i][j+1] + a[i][j]) / 5);
}
}
}
for(int i = 1; i <= n; ++i) // 输出矩阵b
{
for(int j = 1; j <= m; ++j)
{
printf("%d ", b[i][j]);
}
printf("\n");
}
return 0;
}