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;
} 

 

posted on 2016-04-08 23:21  vCoders  阅读(319)  评论(0编辑  收藏  举报

导航