样例输入:
3 2
4 0
-10 8
-2 -2
样例输出:
4
二维前缀和模板题,但是注意细节,像下面这样写有一个点超时:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 210;
int a[N][N];
int sum[N][N];
int n, m;
int ans;
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
//求一下上面矩形的面积
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i-1][j-1]+a[i][j];
}
}
//求一下两个坐标构成的矩形面积
for (int x1 = 1; x1 <= n; x1++) {
for (int y1 = 1; y1 <= m; y1++) {
for (int x2 = 1; x2 <= n; x2++) {
for (int y2 = 1; y2 <= m; y2++) {
int Sum = sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
if (Sum > 0)
ans = max(ans, (x2 - x1 + 1) * (y2 - y1 + 1));
}
}
}
}
cout << ans << endl;
return 0;
}
我们可以加一个优化,让x2从x1开始枚举,不要从1开始枚举。也就是说x1枚举过的x2就不要去枚举了,x2一定在x1下面:
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 210;
int a[N][N];
int sum[N][N];
int n, m;
int ans;
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
}
}
//求一下上面矩形的面积
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i-1][j-1]+a[i][j];
}
}
//求一下两个坐标构成的矩形面积
for (int x1 = 1; x1 <= n; x1++) {
for (int y1 = 1; y1 <= m; y1++) {
for (int x2 = x1; x2 <= n; x2++) {
for (int y2 = 1; y2 <= m; y2++) {
int Sum = sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
if (Sum > 0)
ans = max(ans, (x2 - x1 + 1) * (y2 - y1 + 1));
}
}
}
}
cout << ans << endl;
return 0;
}