zoukankan      html  css  js  c++  java
  • 二分+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"<<'
    ';
            else cout<<ans<<'
    ';
        }    
    } 
  • 相关阅读:
    字典常用操作复习
    列表常用方法复习
    爬虫流程复习
    协程解决素数
    yield 复习
    多线程复习2
    多线程复习1
    异常 巩固3
    logging日志基础示例
    2019最新百度网盘不限速下载教程
  • 原文地址:https://www.cnblogs.com/zsben991126/p/12600807.html
Copyright © 2011-2022 走看看