单调队列的基本应用。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1050
#define inf 2000000000
using namespace std;
int n,m,a,map[maxn][maxn],m1[maxn][maxn][],m2[maxn][maxn][],q1[maxn],q2[maxn],l1,r1,l2,r2,ans=inf;
void get_m1()
{
for (int i=;i<=n;i++)
{
l1=l2=;r1=r2=;
for (int j=m;j>=;j--)
{
while ((l1<=r1) && (q1[l1]>=j+a)) l1++;
while ((l2<=r2) && (q2[l2]>=j+a)) l2++;
while ((l1<=r1) && (map[i][j]>map[i][q1[r1]])) r1--;
while ((l2<=r2) && (map[i][j]<map[i][q2[r2]])) r2--;
q1[++r1]=j;q2[++r2]=j;
m1[i][j][]=map[i][q1[l1]];m1[i][j][]=map[i][q2[l2]];
}
}
}
void get_m2()
{
for (int i=;i<=m;i++)
{
l1=l2=;r1=r2=;
for (int j=n;j>=;j--)
{
while ((l1<=r1) && (q1[l1]>=j+a)) l1++;
while ((l2<=r2) && (q2[l2]>=j+a)) l2++;
while ((l1<=r1) && (m1[j][i][]>m1[q1[r1]][i][])) r1--;
while ((l2<=r2) && (m1[j][i][]<m1[q2[r2]][i][])) r2--;
q1[++r1]=j;q2[++r2]=j;
m2[j][i][]=m1[q1[l1]][i][];m2[j][i][]=m1[q2[l2]][i][];
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&a);
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
scanf("%d",&map[i][j]);
get_m1();
get_m2();
for (int i=;i<=n-a+;i++)
for (int j=;j<=m-a+;j++)
ans=min(ans,m2[i][j][]-m2[i][j][]);
printf("%d\n",ans);
return ;
}