和 这题 差不多,考虑采用垂线法。
把判定改为相邻两个格子异色,统计答案分正方形和矩形统计。
#include <bits/stdc++.h>
using namespace std;
const int N = 1015;
int n, m;
int st[N][N];
int up[N][N], l[N][N], r[N][N], ans1 = 0, ans2 = 0;
int main() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
scanf("%d", &st[i][j]);
}
for (int i = 1; i <= n; i++) l[i][0] = 1, r[i][m + 1] = m, st[i][0] = st[i][m + 1] = 2;
for (int i = 1; i <= m; i++) up[0][i] = 1, st[0][i] = 2;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (st[i][j] == st[i - 1][j]) up[i][j] = i;
else up[i][j] = up[i - 1][j];
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (st[i][j] == st[i][j - 1]) l[i][j] = j;
else l[i][j] = l[i][j - 1];
}
for (int i = 1; i <= n; i++)
for (int j = m; j >= 1; j--) {
if (st[i][j] == st[i][j + 1]) r[i][j] = j;
else r[i][j] = r[i][j + 1];
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
if (i > 1 && st[i][j] != st[i - 1][j]) { //记得判定 st[i][j] != st[i - 1][j]
l[i][j] = max(l[i][j], l[i - 1][j]);
r[i][j] = min(r[i][j], r[i - 1][j]);
}
int x = min((i - up[i][j] + 1), (r[i][j] - l[i][j] + 1));
ans1 = max(ans1, x * x);
ans2 = max(ans2, (i - up[i][j] + 1) * (r[i][j] - l[i][j] + 1));
}
// for (int i = 1; i <= n; i++, puts(""))
// for (int j = 1; j <= m; j++) cout << up[i][j] << ' ';
printf("%d\n%d\n", ans1, ans2);
return 0;
}