※上海交通大学 最小面积子矩阵(java)(矩阵压缩)

题目描述
一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积)
输入描述:
每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K
接下来N行,每行M个数,表示矩阵每个元素的值
输出描述:
输出最小面积的值。如果出现任意矩阵的和都小于K,直接输出-1。
示例1
输入
复制
4 4 10
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
输出
复制
1
import java.util.*;
import java.io.*;
import java.text.* ;
public class Main
{
	static int n;
	static int m;
	static int[][] matrix;
	static int res = Integer.MAX_VALUE;
	static int k;
    public static void main(String[] args){
    	try {
	        BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
	        String[] parts = br.readLine().split(" ");
	        n = Integer.parseInt(parts[0]);
	        m = Integer.parseInt(parts[1]);
	        k = Integer.parseInt(parts[2]);
	        matrix = new int[n][m];
	        for(int i = 0; i < n; i++) {
	        	String[] lines = br.readLine().split(" ");
	        	for(int j = 0; j < m; j++) {
	        		matrix[i][j] = Integer.parseInt(lines[j]);
	        	}
	        }
	        System.out.println(matrixSum());
 	    } catch (IOException e) {
	        e.printStackTrace();
	    }
    }
    public static int matrixSum() {
    	int ans = m*n+1;
    	for(int i = 0; i < n; i++) {
    		int[] tmp = new int[m];
    		for(int j = i; j < n; j++) {
    			for(int l = 0; l < m; l++)
    				tmp[l] += matrix[j][l];
    			int len = getLen(tmp);
    			ans = Math.min(ans, len*(j-i+1));
    		}
    	}
    	if(ans == m*n+1) return -1;
    	return ans;
    }
    private static int getLen(int[] a) {
        int low = 0, high = 0;
        int len = m*n+1;
        int s = 0;
        while ( high<m ) {
            while ( s<k && high<m ) {
                s += a[high];
                high ++;
            }
            while ( s>=k && low<high-1) {
                len = Math.min(len, high-low);
                s -= a[low];
                low ++;
            }
            //先往后扩,再往后缩
            if ( low + 1 == high ) return 1;
        }
        return len;
    }
}

补充:最大子矩阵和

import java.util.*;
import java.io.*;
import java.text.* ;
public class Main
{
	static int n;
	static int m;
	static int[][] matrix;
	static int res = Integer.MAX_VALUE;
    public static void main(String[] args){
    	try {
	        BufferedReader br= new BufferedReader(new InputStreamReader(System.in));
	        String[] parts = br.readLine().split(" ");
	        n = Integer.parseInt(parts[0]);
	        m = Integer.parseInt(parts[1]);
	        matrix = new int[n][m];
	        for(int i = 0; i < n; i++) {
	        	String[] lines = br.readLine().split(" ");
	        	for(int j = 0; j < m; j++) {
	        		matrix[i][j] = Integer.parseInt(lines[j]);
	        	}
	        }
	        System.out.println(matrixSum());
 	    } catch (IOException e) {
	        e.printStackTrace();
	    }
    }
    public static int matrixSum() {
    	int ans = Integer.MIN_VALUE;
    	for(int i = 0; i < n; i++) {
    		int[] tmp = new int[m];
    		for(int j = i; j < n; j++) {
    			for(int l = 0; l < m; l++) {
    				tmp[l] += matrix[j][l];
    			}    		
    			ans = Math.max(ans, ArrSum(Arrays.copyOfRange(tmp, 0, m)));
    		}
    	}
    	return ans;
    }
    private static int ArrSum(int[] dp) {//求最大子序列和
        int max = dp[0];
        for (int i = 1; i < m; i++) {
            dp[i] = Math.max(dp[i], dp[i - 1] + dp[i]);
            max = Math.max(max, dp[i]);
        }
        return max;
    }
}


发布了231 篇原创文章 · 获赞 22 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_43306331/article/details/104214143
今日推荐