题目描述
一个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;
}
}