子矩阵大小
问题描述
【题目描述】
设矩阵的大小为矩阵中所有元素的和,现输入一个NN的矩阵,请设计算法计算最大的非空(大小至少是11)子矩阵的大小。
例如4×4的矩阵为:
1 0 1 1
1 1 1 1
1 1 1 1
0 1 -6 -8
其最大子矩阵为:
1 0 1 1
1 1 1 1
1 1 1 1
子矩阵大小是11。
【输入】
输入是一个N×N的矩阵。输入的第一行给出N(0<N≤100)。再后面的若干行依次输入矩阵各行的元素,用空格作为分隔符,设矩阵中整数的范围都在[−127,127]。
【输出】
输出最大子矩阵的大小。
【输入样例】
4
1 0 1 1
1 1 1 1
1 1 1 1
0 1 -6 -8
【输出样例】
11
算法设计思想
根据题意,子矩阵一定是在某几行之间的。假设我们认为子矩阵在第i行和第j行之间,如何得到i和j呢?通过枚举。枚举所有1<=i<=j<=N,表示最终子矩阵选取的行范围。我们把每一列把第i行到第j行相加,对每一次相加求出最大值,记录为sum,最后得到的sum就是最大子矩阵的值。
算法详细设计
(1)数据结构设计
用int类型定义了一个n储存矩阵的行列数,用二维数组array[10][10]来存储矩阵的元素,从键盘来输入元素。将每一列的元素从第i到第j行相加,记录最大值为sum,然后输出。
(2)算法模块设计
本算法用了两个函数,每个函数都有特定的功能分别再主函数中调用实现。主函数输入矩阵的大小和元素,然后调用MAX(int array[10][10],int n)循环把第i行到第j行相加,对每一次相加求出最大值,利用maxn求出max,当sum大于max时更新最大值sum,然后得到结果。其中两个函数的核心代码如下
下面展示一些 代码段
。
int maxn(int a[],int n)
{
int b=0,i,sum=a[0];
for(i=0;i<n;i++)
{
if(b>0)
b+=a[i];
else
b=a[i];
if(b>sum)
sum=b;
}
return sum;
}
int MAX(int array[10][10],int n)
{
int i,j,k,max=0,sum=-100;
int b[10];
for(i=0;i<n;i++)
{
for(k=0;k<n;k++)//初始化b[]
{
b[k]=0;
}
for(j=i;j<n;j++)
{
for(k=0;k<n;k++)
{
b[k]+=array[j][k];
}
max=maxn(b,k);
if(max>sum)
{
sum=max;
}
}
}
return sum;
}
算法运行与测试
我们先将样例中所给数据输入,如图所示,验证结果可知结果正确。
然后随机输入一组数据如图所示,通过自己计算可知按输入改数据的话,输出结果为15,根据结果可知算法正确。