loj#2334 「JOI 2017 Final」JOIOI 王国

分析

二分答案

判断左上角是否满足

为了覆盖所有范围

我们依次把右下角,左上角,右上角移动到左上角

代码

#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;
}

 

posted @ 2019-09-30 11:01  水题收割者  阅读(301)  评论(0编辑  收藏  举报