P2216 理想的正方形
传送门
思路
双重单调队列,单调队列练手好题。
代码
#include
#define MAXN 1010
using namespace std;
int M[MAXN][MAXN], rowmax[MAXN][MAXN], rowmin[MAXN][MAXN],
colmax[MAXN][MAXN], colmin[MAXN][MAXN], q[MAXN];
int main(void)
{
int a = 0, b = 0, n = 0;
cin >> a >> b >> n;
for (int i = 1; i <= a; i++)
for (int j = 1; j <= b; j++)
cin >> M[i][j];
for (int i = 1; i <= a; i++)
{
int head = 0, tail = 0;
for (int j = 1; j <= b; j++)
{
while (head < tail && q[head] + n <= j)
head++;
while (head < tail && M[i][q[tail - 1]] < M[i][j])
tail--;
q[tail] = j; tail++;
if (j >= n) rowmax[i][j - n + 1] = M[i][q[head]];
}
head = 0, tail = 0;
for (int j = 1; j <= b; j++)
{
while (head < tail && q[head] + n <= j)
head++;
while (headM[i][j])
tail--;
q[tail] = j; tail++;
if (j >= n) rowmin[i][j - n + 1] = M[i][q[head]];
}
}
for (int j = 1; j <= b - n + 1; j++)
{
int head = 0, tail = 0;
for (int i = 1; i <= a; i++)
{
while (head < tail && q[head] + n <= i)
head++;
while (head < tail && rowmax[q[tail - 1]][j] < rowmax[i][j])
tail--;
q[tail] = i; tail++;
if (i >= n) colmax[i - n + 1][j] = rowmax[q[head]][j];
}
head = 0, tail = 0;
for (int i = 1; i <= a; i++)
{
while (head < tail && q[head] + n <= i)
head++;
while (headrowmin[i][j])
tail--;
q[tail] = i; tail++;
if (i >= n) colmin[i - n + 1][j] = rowmin[q[head]][j];
}
}
long long ans = INT32_MAX;
for (int i = 1; i <= a - n + 1; i++)
for (int j = 1; j <= b - n + 1; j++)
ans = min(ans, (long long)(colmax[i][j] - colmin[i][j]));
cout << ans;
return 0;
}