二分+BFS——UCL 2016 J

题意比较难懂,因为是最大化最小值,无脑二分答案即可

/*
每走一步,图上所有数-1,使(1,1)走到(n,m)的路径上数最小的点最大,问这个值
样例1的路线 
9
8   3 3 5
7 3 4   4
        3
*/      
#include<bits/stdc++.h>
using namespace std;
#define N 505

int h[N][N],r,c;

int t[N][N],d[N][N];
int judge(int mid){
    memset(d,-1,sizeof d);
    for(int i=1;i<=r;i++)
        for(int j=1;j<=c;j++)
            t[i][j]=h[i][j]-mid;//最长用多久时间到达该点
    if(t[1][1]<0)return 0;
    queue<pair<int,int>>q;
    q.push(make_pair(1,1));
    d[1][1]=0;    
    int flag=0;
    if(1==r && 1==c)flag=1;
    
    while(q.size()){
        pair<int,int> p=q.front();q.pop();
        int i=p.first,j=p.second;
        if(i==r && j==c)flag=1;
        if(i>1 && d[i-1][j]==-1){
            d[i-1][j]=d[i][j]+1;
            if(d[i-1][j]<=t[i-1][j])
                q.push(make_pair(i-1,j));
        }
        if(i<r && d[i+1][j]==-1){
            d[i+1][j]=d[i][j]+1;
            if(d[i+1][j]<=t[i+1][j])
                q.push(make_pair(i+1,j));
        }
        if(j>1 && d[i][j-1]==-1){
            d[i][j-1]=d[i][j]+1;
            if(d[i][j-1]<=t[i][j-1])
                q.push(make_pair(i,j-1));
        }
        if(j<c && d[i][j+1]==-1){
            d[i][j+1]=d[i][j]+1;
            if(d[i][j+1]<=t[i][j+1])
                q.push(make_pair(i,j+1));
        }
    } 
    /*if(mid==3){
        for(int i=1;i<=r;i++){
            for(int j=1;j<=c;j++)
                cout<<t[i][j]<<" ";
            puts("");
        }
        puts("");
        for(int i=1;i<=r;i++){
            for(int j=1;j<=c;j++)
                cout<<d[i][j]<<" ";
            puts("");
        }
    }*/
    return flag;
}

int main(){
    //freopen("1.in","r",stdin);
    int t;cin>>t;
    while(t--){
        cin>>r>>c;
        int Max=0;
        for(int i=1;i<=r;i++)
            for(int j=1;j<=c;j++)
                scanf("%d",&h[i][j]),Max=max(Max,h[i][j]);
        int L=1,R=Max,ans=-1,mid;
        while(L<=R){
            mid=L+R>>1;
            if(judge(mid))
                ans=mid,L=mid+1;
            else R=mid-1;
        }
        if(ans<=0)cout<<"impossible"<<'\n';
        else cout<<ans<<'\n';
    }    
} 

 

posted on 2020-03-30 20:10  zsben  阅读(119)  评论(0编辑  收藏  举报

导航