考虑一下一维情况,似乎只是一个RMQ问题。一维情况下,就是考虑找出一个区间长度固定的一个区间,对应
m
x
−
m
i
n
mx-min
mx−min最小即可.
在二维的情况,考虑枚举该正方形的左上角,需要一个数据结构支持查询二维的一个最大值.
考虑
s
t
st
st表来实现这个功能,因为查询比较多而且是静态的.
然后该
s
t
st
st表是一个二维形式呈现的.
m
x
(
i
,
j
,
k
)
:
mx(i,j,k):
mx(i,j,k):以
(
i
,
j
)
(i,j)
(i,j)为左上角,长度为
2
k
2^k
2k的正方形区域中的最大值.
m
n
(
i
,
j
,
k
)
mn(i,j,k)
mn(i,j,k):以
(
i
,
j
)
(i,j)
(i,j)为左上角,长度为
2
k
2^k
2k正方形区域的最小值.
m
x
(
i
,
j
,
k
)
=
m
a
x
(
m
x
(
i
,
j
,
k
−
1
)
,
m
a
x
(
m
x
(
i
,
j
+
(
1
<
<
k
)
,
k
−
1
)
,
m
x
(
i
+
(
1
<
<
k
)
,
j
,
k
−
1
)
,
m
x
(
i
+
(
1
<
<
k
)
,
j
+
(
1
<
<
k
)
,
k
−
1
)
mx(i,j,k) =max(mx(i,j,k-1),max(mx(i,j+(1<<k),k-1),mx(i+(1<<k),j,k-1),mx(i+(1<<k),j+(1<<k),k-1)
mx(i,j,k)=max(mx(i,j,k−1),max(mx(i,j+(1<<k),k−1),mx(i+(1<<k),j,k−1),mx(i+(1<<k),j+(1<<k),k−1)
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000+5;
const int INF = 1e9+7;
typedef long long ll;
typedef pair<int,int> pii;
#define all(a) (a).begin(), (a).end()
#define pb(a) push_back(a)
vector<int> G[maxn];
int a,b,n;
int mp[maxn][maxn];int mx[maxn][maxn][10],mn[maxn][maxn][10];
int m;//__lg(n)
int query(int x,int y){
//查询左上角是(x,y),长度为N*N的正方形对应的最大值减去最小值
int Mx = 0,Mn = INF;
Mx = max(max(mx[x][y][m],mx[x+n-(1<<m)][y+n-(1<<m)][m]),max(mx[x+n-(1<<m)][y][m],mx[x][y+n-(1<<m)][m]));
Mn = min(min(mn[x][y][m],mn[x+n-(1<<m)][y+n-(1<<m)][m]),min(mn[x+n-(1<<m)][y][m],mn[x][y+n-(1<<m)][m]));
return Mx - Mn;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>a>>b>>n;
for(int i=1;i<=a;i++){
for(int j=1;j<=b;j++) cin>>mp[i][j],mx[i][j][0] = mn[i][j][0] = mp[i][j];
}
for(int k=1;k<=__lg(n);k++){
for(int i=1;i+(1<<k-1)<=a;i++){
for(int j=1;j+(1<<k-1)<=b;j++){
mx[i][j][k] = max(mx[i][j][k-1],max(mx[i+(1<<k-1)][j][k-1],max(mx[i+(1<<(k-1))][j+(1<<k-1)][k-1],mx[i][j+(1<<k-1)][k-1])));
mn[i][j][k] = min(mn[i][j][k-1],min(mn[i+(1<<k-1)][j][k-1],min(mn[i+(1<<(k-1))][j+(1<<k-1)][k-1],mn[i][j+(1<<k-1)][k-1])));
}
}
}
m = __lg(n);
int ans = INF;
for(int i=1;i+n-1<=a;i++){
for(int j=1;j+n-1<=b;j++){
ans = min(ans,query(i,j));
}
}
cout<<ans<<"\n";
}