题意比较难懂,因为是最大化最小值,无脑二分答案即可
/* 每走一步,图上所有数-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<<' '; } }