分析
二分答案
判断左上角是否满足
为了覆盖所有范围
我们依次把右下角,左上角,右上角移动到左上角
代码
#include<bits/stdc++.h>
using namespace std;
int a[2010][2010],n,m,Ans=1e9+7,mx,mn=1e9+7;
inline bool ck(int x){
int i,j,k,l=mn+x,r=mx-x,lim=m;
for(i=1;i<=n;i++){
for(j=1;j<=lim;j++)
if(a[i][j]<r)break;
lim=min(lim,j-1);
for(j=lim+1;j<=m;j++)
if(a[i][j]>l)return 0;
}
return 1;
}
inline void work(){
if(ck(0)){
puts("0");
exit(0);
}
int le=0,ri=mx-mn;
while(ri-le>1){
int mid=(le+ri)>>1;
if(ck(mid))ri=mid;
else le=mid;
}
Ans=min(Ans,ri);
return;
}
int main(){
int i,j,k;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&a[i][j]),mn=min(mn,a[i][j]),mx=max(mx,a[i][j]);
work();
for(i=1;i<=n/2;i++)swap(a[i],a[n-i+1]);
work();
for(i=1;i<=n;i++)reverse(a[i]+1,a[i]+m+1);
work();
for(i=1;i<=n/2;i++)swap(a[i],a[n-i+1]);
work();
cout<<Ans;
return 0;
}