题目链接:​​点击打开链接​

最大子矩阵

Time Limit: 30000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 4135    Accepted Submission(s): 2151



Problem Description

给你一个m×n的整数矩阵,在上面找一个x×y的子矩阵,使子矩阵中所有元素的和最大。

 


Input

输入数据的第一行为一个正整数T,表示有T组测试数据。每一组测试数据的第一行为四个正整数m,n,x,y(0<m,n<1000 AND 0<x<=m AND 0<y<=n),表示给定的矩形有m行n列。接下来这个矩阵,有m行,每行有n个不大于1000的正整数。

 


Output

对于每组数据,输出一个整数,表示子矩阵的最大和。

 


Sample Input

1

4 5 2 2

3 361 649 676 588

992 762 156 993 169

662 34 638 89 543

525 165 254 809 280

 


Sample Output

2474

 

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int m,n,x,y;
int map[1001][1001]; //以 map [ i ] [ j ] 表示前 i 行前 j 列的矩阵和,
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(map,0,sizeof(map));
scanf("%d %d %d %d",&m,&n,&x,&y);
int a;
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&a);
map[i][j]=map[i-1][j]+a;
}
}
int mmax=0;
for(int i=x;i<=m;i++) // 因为题意要求 x * y 的矩阵,所以行数从 x 开始,
{
for(int j=y;j<=n;j++) // 列数从 y 开始
{
int sum=0;
for(int k=j-y+1;k<=j;k++) // 控制 k 的移动的范围为 y;这个小循环完全结束才找到一个 x*y 的矩阵
{ // 第 n 次小循环完全结束,找到一个以 n-1 列开始的 x*y 的矩阵
sum+=(map[i][k]-map[i-x][k]);
}
mmax=max(mmax,sum);
}
}
printf("%d\n",mmax);
}
return 0;
}