一.题目
返回一个整数数组中最大子矩阵的和。
二.要求
输入一个整形矩阵,矩阵里有正数也有负数。
矩阵中连续的一个或多个整数组成一个子矩阵,每个子矩阵都有一个和。
求所有子矩阵的和的最大值。要求时间复杂度为O(n)。
结对编程要求:
两人结对完成编程任务。
一人主要负责程序分析,代码编程。
一人负责代码复审和代码测试计划。
三.设计思路:
经过和我的搭档的研究,我们最后决定以某一个数字为中心,并扩散开来分别成立1*1,1*2,1*3,2*1.2*2,2*3,3*3的子矩阵,让后通过循环嵌套结构,每次统计子矩阵的和,最后通过比较获得最大的和,最后输出。
#include <iostream> #include <vector> using namespace std; const int N = 101; int a[N][N], p[N][N]; int MaxRecSum(int n) { for (int i = 0; i <= n; ++i) { p[i][0] = 0; p[0][i] = 0; } for ( i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) p[i][j] = p[i-1][j] + p[i][j-1] - p[i-1][j-1] + a[i][j]; } int max = INT_MIN; for ( i = 1; i <= n; ++i) { for (int j = i; j <= n; ++j) { int sum = 0; for (int k = 1; k <= n; ++k) { int temp = p[j][k] - p[j][k-1] - p[i-1][k] + p[i-1][k-1]; if (sum > 0) sum += temp; else sum = temp; if (sum > max) max = sum; } } } return max; } int main() { int n = 3; int num; cout<<"矩阵的规格为三行三列,请输入数值:"<<endl; for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cin >> num; a[i][j] = num; } } cout <<"最大字矩阵的和为:"<< MaxRecSum(n) << endl; for ( i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { cout <<a[i][j]<<" "; } cout<<endl; } return 0; }
四.运行结果截图:
五.实验总结及合作感受
本次实验是上一次求最大子数组的升级版,上一次只是在一个维度上嵌套两次循环结构,就能够解决多次循环并求和比较的问题,但是这次的实验变成了二维的矩阵,寻找最大子矩阵的过程要比上一次难了许多,在确定如何寻找最大子矩阵的问题上,我们花费的时间最多,既要把每一个子矩阵都考虑到,又要不能重复比较,最后通过多次尝试,多次修改,实现了最后的功能。
六.结队成员合照
左:范德一 右:赵永恒