一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵

时间:2023-03-08 15:51:00
一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵
题目描述:

一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积)

输入:

每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K
接下来N行,每行M个数,表示矩阵每个元素的值

输出:

输出最小面积的值。如果出现任意矩阵的和都小于K,直接输出-1。

样例输入:
4 4 10
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
样例输出:
1

首先这个题应该是有一个动态规划的解法,不过好像复杂度也要到O(n^3logn),所以这里直接暴力了。但是为了节省时间首先计算出从左上角开始的矩阵的和,然后根据这个和可以求各个矩阵的值

 //计算左上角为(1,1)的所有子矩阵的和,需要O(N^2)的时间。
//此时只需要O(1)的时间就可以算出每个子矩阵的和。
//枚举次数依然不变。总时间复杂度为O(N^4)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
//freopen("t","r",stdin);
int m,n,k;
while(cin>>m>>n>>k){
int ma[][];
for(int i=;i<m;i++){
for(int j=;j<n;j++){
cin>>ma[i][j];
}
}
int sum[][];
memset(sum,,sizeof(sum));
sum[][]=ma[][];
for(int i=;i<m;i++){
sum[i][]=ma[i][]+sum[i-][];
}
for(int i=;i<n;i++){
sum[][i]=ma[][i]+sum[][i-];
}
for(int i=;i<m;i++){
for(int j=;j<n;j++){
sum[i][j]+=sum[i][j-];
for(int k=;k<=i;k++){
sum[i][j]+=ma[k][j];
}
}
} int minsize=;
for(int a=;a<m;a++){
for(int b=a;b<m;b++){
for(int c=;c<n;c++){
for(int d=c;d<n;d++){
int s=;
if(a==&&b==&&c==&&d==){
s=sum[][];
}
else if(a==&&c==){
s=sum[b][d];
}
else if(a==){
s=sum[b][d]-sum[b][c-];
}
else if(c==){
s=sum[b][d]-sum[a-][d];
}
else{
s=sum[b][d]+sum[a-][c-]-sum[a-][d]-sum[b][c-];
}
if(s>=k){
int sizee=(b-a+)*(d-c+);
if(minsize>sizee){
minsize=sizee;
}
}
}
}
}
}
if(minsize==){
cout<<-<<endl;
}
else{
cout<<minsize<<endl;
}
}
return ;
}