2010上交:最小面积子矩阵
- 题目描述:
-
一个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
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN=105; int n,m,k; int a[MAXN][MAXN]; int sum[MAXN][MAXN]; int area(int i,int j,int x,int y) { return (x-i+1)*(y-j+1); } int main() { while(scanf("%d%d%d",&n,&m,&k)!=EOF) { for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&a[i][j]); sum[1][1]=a[1][1]; for(int i=2;i<=n;i++) sum[i][1]=sum[i-1][1]+a[i][1]; for(int j=2;j<=m;j++) sum[1][j]=sum[1][j-1]+a[1][j]; for(int i=2;i<=n;i++) for(int j=2;j<=m;j++) sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j];//sum[i][j]记录 左上角为a[1][1],右下角为a[i][j]的子矩阵之和 int res=MAXN*MAXN; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) for(int x=i;x<=n;x++) for(int y=j;y<=m;y++) { int z=sum[x][y]-sum[i-1][y]-sum[x][j-1]+sum[i-1][j-1]; if(z>=k) { res=min(res,area(i,j,x,y)); } } if(res==MAXN*MAXN) printf("-1\n"); else printf("%d\n",res); } return 0; }