
文章目录
- 💯前言
- 💯题目背景与描述
- 题目描述
- 输入格式
- 输出格式
- 输入输出样例
- 说明与提示
 
 
- 💯分析与解决方案
- 解法一:我的做法
- 代码实现
- 解题思路
- 优点与局限性
 
- 解法二:老师的做法
- 代码实现
- 解题思路
- 优点与局限性
 
- 两种方法的对比与优化
- 优化建议
 
 
- 💯总结

💯前言
- 在编程学习的过程中,我们经常会遇到一些基础但极具锻炼意义的题目,它们不仅可以帮助我们巩固对数据结构的理解,还能提升逻辑思维能力。这篇文章以一道求矩阵边缘元素之和的题目为切入点,展开对解题过程的分析。通过对比两种不同的解法,我们将探索从代码实现到优化的全流程,不仅涵盖基本的编程技巧,还会进一步拓展对于内存管理与代码效率的理解。无论你是初学者还是经验丰富的程序员,相信本次讨论都能带给你一些启发。
 C++ 参考手册
  
💯题目背景与描述
本次我们探讨的题目来源于一道经典的编程练习题,具体内容如下:
 B2101 计算矩阵边缘元素之和
 
题目描述
输入一个整数矩阵,计算位于矩阵边缘的元素之和。
所谓矩阵边缘的元素,就是第一行和最后一行的元素以及第一列和最后一列的元素。
输入格式
- 第 1 行包含两个整数,分别为行数 m m m 和列数 n n n,两个整数之间空格隔开。
- 第 2 行开始有 m m m 行数据,每行包含 n n n 个整数,整数之间空格隔开。
输出格式
- 输出对应矩阵的边缘元素和。
输入输出样例
输入:
3 3
3 4 1
7 1 1
2 0 1
输出:
15
说明与提示
- 1 ≤ m , n ≤ 100 1 \leq m, n \leq 100 1≤m,n≤100:保证答案在 int 类型范围内。
- 代码在遍历数组的过程中判断属于边缘的元素,仅对数组中的每个元素遍历了一遍,是不会存在重复统计的问题的。
💯分析与解决方案
这个题目考察了矩阵的基本操作和条件判断逻辑,要求高效计算边缘元素的累加和。接下来,我们分别分析两种解决方案:一种是我的做法,另一种是老师的做法,并对两者的实现与思路进行对比。
解法一:我的做法
代码实现
#include <iostream>
using namespace std;
int arr[105][105];
int main()
{
    int m, n;
    cin >> m >> n;
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
            cin >> arr[i][j];
        }
    }
    int result = 0;
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
            if(i == 0 || i == m - 1 || j == 0 || j == n - 1)
                result += arr[i][j];
        }
    }
    cout << result << endl;
    return 0;    
}

解题思路
-  输入与存储: - 首先读取矩阵的行数  
        
         
          
          
            m 
           
          
         
           m 
          
         
       m 和列数  
        
         
          
          
            n 
           
          
         
           n 
          
         
       n,并将矩阵存储在一个二维数组 arr中。
- 利用嵌套的双重 for循环,依次读取每个矩阵元素,存储到二维数组的对应位置。
 
- 首先读取矩阵的行数  
        
         
          
          
            m 
           
          
         
           m 
          
         
       m 和列数  
        
         
          
          
            n 
           
          
         
           n 
          
         
       n,并将矩阵存储在一个二维数组 
-  遍历与条件判断: - 使用另一组嵌套的双重 for循环,对整个矩阵进行逐元素的遍历。
- 在遍历过程中,通过条件判断是否为矩阵的边缘元素: 
    - 边缘元素满足以下任一条件: 
      - 第一行: i = = 0 i == 0 i==0
- 最后一行: i = = m − 1 i == m-1 i==m−1
- 第一列: j = = 0 j == 0 j==0
- 最后一列: j = = n − 1 j == n-1 j==n−1
 
 
- 边缘元素满足以下任一条件: 
      
- 如果条件成立,将当前元素累加到结果 result中。
 
- 使用另一组嵌套的双重 
-  输出结果: - 遍历完成后,输出累加结果 result,即矩阵边缘元素的总和。
 
- 遍历完成后,输出累加结果 
优点与局限性
-  优点: - 逻辑清晰,易于理解: 
    - 通过条件判断筛选边缘元素,结构直观。
 
- 矩阵存储方便: 
    - 使用二维数组存储矩阵,方便后续操作。
 
 
- 逻辑清晰,易于理解: 
    
-  局限性: - 内存占用高: 
    - 当矩阵较大(如  
          
           
            
            
              100 
             
            
              × 
             
            
              100 
             
            
           
             100 \times 100 
            
           
         100×100)时,二维数组 arr需要较大的内存空间,可能造成内存浪费。
 
- 当矩阵较大(如  
          
           
            
            
              100 
             
            
              × 
             
            
              100 
             
            
           
             100 \times 100 
            
           
         100×100)时,二维数组 
- 效率有优化空间: 
    - 遍历整个矩阵,同时对非边缘元素进行了不必要的条件判断。
 
 
- 内存占用高: 
    
解法二:老师的做法
代码实现
#include <iostream>
using namespace std;
int main()
{
    int m, n, t;
    cin >> m >> n;
    int result = 0;
    for(int i = 0; i < m; i++)
    {
        for(int j = 0; j < n; j++)
        {
            cin >> t;
            if(i == 0 || i == m - 1 || j == 0 || j == n - 1)
                result += t;
        }
    }
    cout << result << endl;
    return 0;    
}

解题思路
-  输入与处理: - 通过嵌套 for循环直接输入矩阵元素,无需存储矩阵。
- 利用一个临时变量 t,逐一读取每个矩阵元素。
 
- 通过嵌套 
-  边缘元素判断与累加: - 在输入的同时,通过条件判断是否为矩阵边缘元素: 
    - 第一行: i = = 0 i == 0 i==0
- 最后一行: i = = m − 1 i == m-1 i==m−1
- 第一列: j = = 0 j == 0 j==0
- 最后一列: j = = n − 1 j == n-1 j==n−1
 
- 如果是边缘元素,直接累加到结果变量 result中。
 
- 在输入的同时,通过条件判断是否为矩阵边缘元素: 
    
-  输出结果: - 遍历完成后,直接输出累加结果 result。
 
- 遍历完成后,直接输出累加结果 
优点与局限性
-  优点: - 节省内存: 
    - 使用临时变量 t,无需存储整个矩阵,节省了大量内存。
 
- 使用临时变量 
- 高效简洁: 
    - 避免了对非边缘元素的额外遍历或判断。
 
- 适合特定需求: 
    - 如果只需边缘元素的累加和,代码结构最优。
 
 
- 节省内存: 
    
-  局限性: - 缺乏灵活性: 
    - 矩阵未被存储,无法在后续代码中访问或处理矩阵其他元素。
 
- 扩展性较弱: 
    - 如果需要对矩阵进行更多复杂操作(如计算特定行的最大值),无法复用输入。
 
 
- 缺乏灵活性: 
    
两种方法的对比与优化
| 比较维度 | 我的做法 | 老师的做法 | 
|---|---|---|
| 存储方式 | 使用二维数组存储整个矩阵 | 不存储矩阵,直接用临时变量处理 | 
| 内存占用 | 较高(需存储 m × n m \times n m×n 个元素) | 较低(只用一个临时变量 t) | 
| 代码复杂度 | 逻辑稍复杂,需两次遍历 | 逻辑简单,单次遍历即可完成 | 
| 适用场景 | 矩阵需多次访问或进一步处理 | 仅需一次性计算边缘元素之和 | 
优化建议
-  减少重复判断: - 可将边缘元素的处理分为两部分: 
    - 第一行和最后一行直接累加。
- 中间行只处理第一列和最后一列。
 
- 示例代码:
 for (int j = 0; j < n; j++) { result += arr[0][j]; if (m > 1) result += arr[m-1][j]; } for (int i = 1; i < m-1; i++) { result += arr[i][0]; if (n > 1) result += arr[i][n-1]; }
- 可将边缘元素的处理分为两部分: 
    
-  扩展性优化: - 如果矩阵需要进一步处理,可以在老师代码的基础上稍作修改,使用动态存储(如 STL 容器 vector)以兼顾灵活性和效率。
 
- 如果矩阵需要进一步处理,可以在老师代码的基础上稍作修改,使用动态存储(如 STL 容器 
💯总结
通过本次讨论,我们深入分析了两个解法的实现逻辑及优劣,并提出了优化建议。老师的做法内存占用低,适用于只需一次计算的场景;而我的做法适合需要存储矩阵、进行后续操作的需求。在编程实践中,应根据具体需求选择最优方案,同时时刻考虑代码的可读性与扩展性。






























