2147 最大子矩阵

2147 最大子矩阵

⭐️难度:中等
考点:2022、双指针、省赛、二分

2147 最大子矩阵_第1张图片
2147 最大子矩阵_第2张图片

import java.util.Scanner;
import java.util.Arrays;

public class Main {
    static int[][] a;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int m = sc.nextInt();
        a = new int[90][100010];
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m ; j++) {
                a[i][j] = sc.nextInt();
            }
        }
        int limit = sc.nextInt();


        int ans = 0;
        // 直接暴力
        for (int i = 1; i <= n ; i++) { //左上角y坐标
            for (int j = 1; j <= m ; j++) { // 左上角x坐标
                for (int l = i; l <= n; l++) { // 左下角

                    int maxl = Integer.MAX_VALUE;
                    int maxr = Integer.MAX_VALUE;

                    for (int r = j; r <= m ; r++) {  // 右下角
                        // 先打印下标看遍历的对不对
                        // System.out.println( "i:"+i+" j:"+j+" l:"+l+" r:"+r);

                        //运行超时,做个剪枝,得出答案后小于这个答案的子矩阵都不用看了
                        //还有10个超时,再做个剪枝,如果子矩阵内稳定性大于limit了,那么比它大的子矩阵稳定性也必定超过limit
                        if((r-j+1)*(l-i+1) <= ans || l >= maxl || r >= maxr){
                            continue;
                        }
                        // 计算子矩阵稳定性
                        if(count(i,j,l,r) <= limit){
                            //计算子矩阵面积
                            int num = (r-j+1)*(l-i+1);
                            if(ans < num) ans = num;
                        }else {
                            // 子矩阵的稳定性超过limit了,标记一下当前子矩阵大小,也就是左下角和右下角的下标
                            maxl = l;
                            maxr = r;
                            break;
                        }
                    }
                }
            }
        }
        System.out.println(ans);
    }
    static int count(int i,int j ,int l,int r){
        int max = Integer.MIN_VALUE;
        int min = Integer.MAX_VALUE;
        for (int x = i; x <= l; x++) {
            for (int y = j; y <= r ; y++) {
                max = Math.max(max,a[x][y]);
                min = Math.min(min,a[x][y]);
            }
        }
        return max-min;
    }
}

没用二分+双指针,
用的暴力+剪枝:
剪枝1:得出答案后,小于这个面积的子矩阵都不用看了
剪枝2:如果子矩阵内稳定性大于limit了,那么在左上角确定的情况下,比它大的子矩阵稳定性也必定超过limit

2147 最大子矩阵_第3张图片

你可能感兴趣的:(#,刷题,矩阵,java,android)