【C++】B2104 矩阵加法
文章目录
- 💯前言
- 💯题目描述
- 输入格式
- 输出格式
- 输入输出示例
- 💯我的解法
- 解法分析
- 解法优缺点
- 💯老师的解法
- 解法分析
- 优缺点对比
- 💯思路对比与优化
- 对比总结
- 改进与优化
- 💯小结
💯前言
- 矩阵加法是程序设计中一个非常基础但又非常具有实际应用价值的操作。通过对两矩阵的元素进行逐一相加,我们能够快速实现各种场景中的数值计算。这道题目 “矩阵加法” 出自洛谷题库 B2104,是一道典型的二维数组操作题。在这篇文章中,我们将对该题进行全面的解析,涵盖题目描述、我的解法、老师的解法、对比分析以及进一步的优化和拓展。
C++ 参考手册
💯题目描述
B2104 矩阵加法
题目编号:B2104 矩阵加法
题目要求:
输入两个 (n \times m) 行列的矩阵 (A) 和 (B),输出它们的和矩阵 (A + B)。矩阵加法的规则是两个矩阵中对应位置的值进行加和,具体叙述如下。
输入格式
- 第一行包含两个整数 (n) 和 (m),表示矩阵的行数和列数 (1 ≤ (n), (m) ≤ 100)。
- 接下来 (n) 行,每行 (m) 个整数,表示矩阵 (A) 的元素。
- 接下来 (n) 行,每行 (m) 个整数,表示矩阵 (B) 的元素。
矩阵 A 和矩阵 B 的元素范围均为:1 ≤ 元素值 ≤ 1000。
输出格式
输出矩阵的加法结果,每行输出 (m) 个整数,相邻两个整数之间用单个空格隔开。
输入输出示例
输入示例 #1:
3 3
1 2 3
1 2 3
1 2 3
1 2 3
4 5 6
7 8 9
输出示例 #1:
2 4 6
5 7 9
8 10 12
通过示例可以看出,矩阵加法的核心在于将两个矩阵的对应位置元素直接相加,并输出到结果矩阵中。
💯我的解法
以下是我完成题目的代码实现:
#include <iostream>
using namespace std;int arr1[1005][1005];
int arr2[1005][1005];int main()
{int n, m;cin >> n >> m;for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){cin >> arr1[i][j];}}for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){cin >> arr2[i][j];}}for(int i = 0; i < n; i++){for(int j = 0; j < m; j++){cout << arr1[i][j] + arr2[i][j] << " ";}cout << endl;}return 0;
}
解法分析
-
输入处理:
- 首先通过
cin
分别读取矩阵 (A) 和矩阵 (B) 的行列数 (n) 和 (m)。 - 使用两个嵌套循环将两个矩阵的值分别存储到二维数组
arr1
和arr2
中。
- 首先通过
-
矩阵加法计算:
- 再次通过两个嵌套循环,逐一访问矩阵的每个元素,将
arr1[i][j] + arr2[i][j]
的结果直接输出。
- 再次通过两个嵌套循环,逐一访问矩阵的每个元素,将
-
结果输出:
- 使用
cout
将结果矩阵按要求格式化输出,并保证每行换行。
- 使用
解法优缺点
优点:
- 代码逻辑清晰,分为输入、计算和输出三个步骤,结构化程度较高。
- 程序功能正确,可以顺利通过题目测试。
缺点:
- 数组大小定义为 1005 × 1005,虽然可以确保安全性,但实际题目规模上限是 100 × 100,存在内存浪费。
- 输出格式中,每行最后一个数后多输出了一个空格(不符合严格输出要求)。
💯老师的解法
以下是老师提供的代码实现:
#include <iostream>
#include <cstdio>
using namespace std;const int N = 110;
int arr[N][N];
int m, n;int main()
{cin >> m >> n;int i = 0;int j = 0;for (i = 0; i < m; i++){for (j = 0; j < n; j++){cin >> arr[i][j];}}int num = 0;int c = 0;for (i = 0; i < m; i++){for (j = 0; j < n; j++){cin >> num;arr[i][j] += num;}}for (i = 0; i < m; i++){for (j = 0; j < n; j++){printf("%d ", arr[i][j]);}printf("\n");}return 0;
}
解法分析
-
存储方式优化:
- 老师的代码使用一个数组
arr
同时存储矩阵 (A) 和结果矩阵 (C)。在输入矩阵 (B) 时,直接对数组arr
的值进行累加,避免了创建额外的存储空间。
- 老师的代码使用一个数组
-
代码逻辑:
- 将矩阵 (A) 直接存储在
arr
中,然后在读取矩阵 (B) 时,将值直接累加到arr
。 - 最后,直接遍历输出结果矩阵。
- 将矩阵 (A) 直接存储在
-
输出效率:
- 使用了
printf
进行格式化输出,相比cout
有一定的性能优势。
- 使用了
优缺点对比
优点:
- 空间效率高:
- 通过复用一个数组完成矩阵存储和加法操作,节省了内存空间。
- 逻辑简洁:
- 不需要单独定义数组
arr2
或进行单独的加法操作。
- 不需要单独定义数组
缺点:
- 输出格式中,每行最后一个数字后仍然多输出了空格。
- 硬编码的数组大小
N = 110
限制了矩阵规模的灵活性。 - 冗余变量
c
未被使用。
💯思路对比与优化
对比总结
- 我的解法使用了两个数组
arr1
和arr2
,而老师的解法通过一个数组arr
完成了矩阵存储和加法操作。 - 我的代码逻辑稍显冗余,但清晰直观;老师的代码则在存储和逻辑上更加紧凑。
- 两种代码在输出格式上都需要改进,避免每行最后一个数字后多输出一个空格。
改进与优化
-
动态分配存储空间:
- 改用
std::vector
动态分配二维数组,避免硬编码数组大小,提升灵活性。
- 改用
-
严格输出格式:
- 控制空格输出,保证输出格式完全符合要求。
-
去除冗余代码:
- 清理未使用变量,简化代码逻辑。
优化后的代码如下:
#include <iostream>
#include <vector>
using namespace std;int main()
{int m, n;cin >> m >> n;vector<vector<int>> arr(m, vector<int>(n));// 输入矩阵 Afor (int i = 0; i < m; i++){for (int j = 0; j < n; j++){cin >> arr[i][j];}}// 输入矩阵 B,并进行加法for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){int num;cin >> num;arr[i][j] += num;}}// 输出结果矩阵for (int i = 0; i < m; i++){for (int j = 0; j < n; j++){cout << arr[i][j];if (j < n - 1) cout << " "; // 控制空格输出}cout << endl;}return 0;
}
💯小结
通过对矩阵加法题目的详细解析和两种代码的分析,我们可以发现:
- 在基础算法题中,代码的正确性和高效性是核心,但规范的输出格式与代码的可读性同样重要。
- 简化存储结构和逻辑能够提升程序的空间效率,但需要确保代码清晰直观。
- 灵活的存储方式(如
std::vector
)能使代码更具扩展性和适应性。
希望本文能够帮助读者理解矩阵加法的实现方法,同时为解决类似问题提供新的思路!