用暴力查找会超时。
思路:存在一些和之前计算过了就不用再计算了。
例如:
1
4 5 2 3
4 5 2 3
3 | 361 | 649 | 676 | 588 |
992 | 762 | 156 | 993 | 169 |
662 | 34 | 638 | 89 | 543 |
525 | 165 | 254 | 809 | 280 |
第1次计算(竖着)
3+992 | 361+762 | 649+156 | 676+933 | 588+169 |
设最大值m = 0;
第一次计算 sum = 3+992 +361+762 + 649+156
第二次计算 sum = 3+992 +361+762 + 649+156 + 676+933 - 3-922 (红色的为重复计算部分)
第三次计算 sum = 361+762+649+156+676+933+588+169-361-762
第2次计算(竖着)
992+662 | 762+34 | 156+638 | 933+89 | 169+543 |
第一次计算 sum = 992+662+762+34+156+638
第二次计算 sum = 992+662+762+34+156+638+922+89-992-662
第三次计算 sum = 762+34+156+638+922+89+169+543-762-34
横着和竖着的地方都有重复计算的地方,计算过的地方就可以不用一直计算,用一个数组记录。
#include <iostream>
using namespace std;
#define MAX 1001
int g[MAX][MAX];
int s[MAX];
int num, line, row, x, y;
int max(int n[])//计算每一行
{
int i, nx, ny, m, sum;
nx = 0;
ny = x;
m = 0;
for (i=0; i<y; i++)
m += n[i];
sum = m;
while (ny!=row)
{
m = m - n[nx] + n[ny];
nx++;
ny++;
if (sum < m)
sum = m;
}
return sum;
}
int main()
{
int i, j, m, sum, nx, ny, t;
cin>>num;
while (num--)
{
cin>>line>>row>>x>>y;
for (i=0; i<line; i++)//记录每一列
for (j=0; j<row; j++)
scanf("%d", &g[i][j]);
m = 0;
for (j=0; j<row; j++)
{
sum = 0;
for (i=0; i<y; i++)
sum += g[i][j];
s[j] = sum;
}
m = max(s);
nx = 0;
ny = x;
for (i=0; i<line-x; i++)
{
for (j=0; j<row; j++)
s[j] = s[j] - g[nx][j] + g[ny][j];
t = max(s);
if (t > m)
m = t;
nx++;
ny++;
}
cout<<m<<endl;
}
return 0;
}