题目明确表示要用n3的的算法做。
因此枚举矩阵的上下边界和右边界,再用两个单调队列维护左边界。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 505;
int t, n, m, num[maxn][maxn];
int maxx[maxn], minn[maxn];
int h1, h2, t1, t2, qmax[maxn], qmin[maxn];
void solve() {
int ans = 0;
for (int i = 1; i <= n; ++i) {
for (int e = 1; e <= n; ++e) {
maxx[e] = 0, minn[e] = 99999999;
}
for (int j = i; j <= n; ++j) {
h1 = h2 = 1, t1 = t2 = 0;
for (int k = 1, p = 0; k <= n; ++k) {
maxx[k] = max(maxx[k], num[j][k]);
minn[k] = min(minn[k], num[j][k]);
while (h1 <= t1 && maxx[qmax[t1]] < maxx[k]) {
--t1;
}
while (h2 <= t2 && minn[qmin[t2]] > minn[k]) {
--t2;
}
qmax[++t1] = k, qmin[++t2] = k;
while (h1 <= t1 && h2 <= t2 && maxx[qmax[h1]] - minn[qmin[h2]] > m) {
if (qmax[h1] < qmin[h2]) {
p = qmax[h1++];
} else {
p = qmin[h2++];
}
}
ans = max(ans, (j - i + 1) * (k - p));
}
}
}
printf("%d\n", ans);
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i) {
for (int j = 1; j <= n; ++j) {
scanf("%d", &num[i][j]);
}
}
solve();
}
return 0;
}