题目
给定一个 M*N 的矩阵MATRIX,要求在此矩阵中寻找一个非空子矩阵,并使得该矩阵的和最大。
输入
要求首先输入两个整数 M 和 N,分别表示矩阵的行和列,再在接下来依次输入矩阵的值MATRIX[I][J]
样例:
3 3 2 -4 1 -1 2 1 4 -2 2
输出
输出一行,包含一个整数,表示 MATRIX中最大子矩阵的元素和
样例:
6
分析
当看到这道题时,脑子里首先是怎么寻找子矩阵,并且要把所有的子矩阵都找一遍。到这里想了想以前学过的线性代数,似乎没想起什么办法寻找子矩阵。对于一个矩阵来说,其子矩阵实在太多了,我们需要找到一个合适的办法来挨个找它的子矩阵。那么我们怎么找,还是这个问题,规律在哪?因此我们需要自己在本子或者其他地方做一些草稿,在这个过程中,我们会发现矩阵他有一个特点:它的形状是一个矩形(这不废话吗)...但是对于矩形,我们可是知道的,我们只要通过一组对角的坐标就能确定这个矩形的位置。因此拿到矩阵里来也是一样的,我们只要两个坐标点就能确定一个子矩阵。那么这就很好办了。我们只需要挨着把所有坐标点都访问一遍就行了。
package 计蒜客;
import java.util.Scanner;
public class Matrix {
public static void main(String[] args)
{
Scanner sc=new Scanner(System.in);
int row=sc.nextInt();
int colum=sc.nextInt();
int[][] matrix=new int[row][colum];
/*
* 输入矩阵的值
*/
for(int i=0;i<row;i++)
{
for(int j=0;j<colum;j++)
{
matrix[i][j]=sc.nextInt();
}
}
/*
* 定义变量valueTMP用来就算矩阵元素和,
valueMAX用来保存最大值
*/
int valueTMP=0;
int valueMAX=matrix[0][0];
/*
* 六层循环,第一二层确定矩阵的第一个坐标
* 第三四层确定矩阵的第二个坐标
* 第五六层把两个坐标点确定的矩阵的元素求和,其实也就是遍历了一遍
* */
for(int a=0;a<row;a++)
{
for(int b=0;b<colum;b++)
{
for(int a1=a;a1<row;a1++)
{
for(int b1=b;b1<colum;b1++)
{
// System.out.print("start:"+a+","+b+"^^^^^^");
// System.out.println("end:"+a1+","+b1);
for(int r=a;r<=a1;r++)
{
for(int c=b;c<=b1;c++)
{
valueTMP+=matrix[r][c];
}
}
if(valueTMP>valueMAX)
{
valueMAX=valueTMP;
}
//每次用完之后,都要把valueTMP置0
valueTMP=0;
}
}
}
}
System.out.println(valueMAX);
}
}
。这里有几个细节需要看一下,第一个就是valueMAX的初始值问题,赋值为矩阵第一个元素,而不是0,考虑一种极端情况,若所有元素都为负数,0的话将会输出错误结果。第二,循环的三四层,也就是确定另一个坐标,我们要从上一个坐标开始,而不是上一个坐标的下一个开始,这里我们考虑另一种极限情况,子矩阵只有一个元素。第三,也就是valueTMP,已经在注释中说到了。
最后,运行结果:
如果将注释的两个输出语句取消注释,将会得到所有情况子矩阵的信息,如下:
扫描二维码关注公众号,回复:
11176047 查看本文章
笔者能想到的解决方法暂时就是这一种,希望大家多多指教,如有问题,请评论区留言!欢迎转载收藏!