zoukankan      html  css  js  c++  java
  • 考研机试 63.最大子矩阵

    时间:2021/03/08

    一.题目描述

    已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。 比如,如下4 * 4的矩阵 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 的最大子矩阵是 9 2 -4 1 -1 8 这个子矩阵的大小是15。

    输入描述

    输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。
    再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N2个整数,
    整数之间由空白字符分隔(空格或者空行)。 已知矩阵中整数的范围都在[-127, 127]。

    输出描述

    测试数据可能有多组,对于每组测试数据,输出最大子矩阵的大小。

    题目链接

    https://www.nowcoder.com/practice/a5a0b05f0505406ca837a3a76a5419b3?

    tpId=40&tqId=21394&rp=1&ru=%2Fta%2Fkaoyan&qru=%2Fta%2Fkaoyan%2Fquestion-ranking&tab=answerKey

    二.算法

    题解

    首先计算total数组,total数组为这一列的部分和,然后计算result数组,result数组为这一列的所有可能的子矩阵和(纵向),然后通过computeMax方法求横向的最大子矩阵和,这样便能求出整个矩阵的最大子矩阵和。最好手写把程序跑一遍,这样便能了解里面的原理了。

    代码

    import java.util.Scanner;
    
    public class Main{
        
        public static void main(String[] args){
            Scanner in = new Scanner(System.in);
            while(in.hasNext()){
                //读取输入
                int n = in.nextInt();
                int[][] num = new int[n][n];
                for(int i = 0; i < n; i++){
                    for(int j = 0; j < n; j++){
                        num[i][j] = in.nextInt();
                    }
                }
                //计算最大矩阵
                int max = Integer.MIN_VALUE;
                int[][] total = new int[n][n];
                int[] result = new int[n];
                for(int i = 0; i < n; i++){
                    total[0][i] = num[0][i];
                }
                for(int i = 1; i < n; i++){
                    for(int j = 0; j < n; j++){
                        total[i][j] = total[i - 1][j] + num[i][j];
                    }
                }
                for(int i = 0; i < n; i++){
                    for(int j = i; j < n; j++){
                        for(int k = 0; k < n; k++){
                            if(i == 0){
                                result[k] = total[j][k];
                            }else{
                                result[k] = total[j][k] - total[i - 1][k];
                            }
                        }
                        max = Math.max(max, computeMax(result));
                    }
                }
                System.out.println(max);
            }
        }
        
        //计算当前的最大子矩阵
        public static int computeMax(int[] result){
            int n = result.length;
            int[] temp = new int[n];
            temp[0] = result[0];
            int max = result[0];
            for(int i = 1; i < n; i++){
                temp[i] = (temp[i - 1] > 0) ? (temp[i - 1] + result[i]) : result[i];
                max = Math.max(max, temp[i]);
            }
            return max;
        }
    }
    努力,向上,自律
  • 相关阅读:
    安卓基础之读取联系人的姓名和电话
    Android基础之6.0系统以上的权限分配
    Android基础之内容提供者的实现
    android中Post方式发送HTTP请求
    安卓基础之Sqlite数据库最最基础操作
    安卓基础之Get方式发送http请求
    安卓基础之国际化
    安卓基础之主题/样式
    安卓基础之Activity的生命周期
    Kotlin入门(14)继承的那些事儿
  • 原文地址:https://www.cnblogs.com/machi12/p/14502786.html
Copyright © 2011-2022 走看看