题目链接:点击打开链接
题意:一个n*n的矩阵中的每一个值代表这个位置有这么高的山,为从(1,1)这个点走到(n,n)这个点,最高的海拔和最小的海拔之差最小。
题解:暴搜会超时=-=,所以换种思路,首先海拔高度的区间为【0,110】,那么意味着最大的差也不过是110,我们是否可以去枚举这个差,可以。所以不如换一种想法。我们去合法的区间。用二分去枚举。
看代码
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 105;
int mou[maxn][maxn];
int book[maxn][maxn];
int mov[4][2] = {1,0,-1,0,0,-1,0,1};
int n;
struct node{
int x;
int y;
};
bool bfs(int low,int high){
memset(book,0,sizeof(book));
queue<node> q;
while(!q.empty()) q.pop();
if(mou[1][1] < low || mou[1][1] > high){
return false;
}
node now,next;
now.x = 1;
now.y = 1;
book[1][1] = 1;
q.push(now);
while(!q.empty()){
now = q.front();
q.pop();
if(now.x == n && now.y == n ){
return true;
}
for(int i = 0 ; i < 4 ; i ++){
next.x = now.x + mov[i][0];
next.y = now.y + mov[i][1];
if(next.x >= 1 && next.x <= n && next.y >= 1 && next.y <= n && !book[next.x][next.y] && mou[next.x][next.y] >= low &&mou[next.x][next.y] <= high){
q.push(next);
book[next.x][next.y] = 1;
}
}
}
return false ;
}
bool judge(int x){
for(int low = 0; low+x < 110 ; low ++){
if(bfs(low,low+x)) return true;
}
return false;
}
int main(){
cin >> n;
for(int i = 1 ; i<= n ; i ++){
for(int j = 1; j <= n ; j ++){
scanf("%d",&mou[i][j]);
}
}
int l = 0 ,r = 110;
int mid ;
while(l <= r){
mid = (l+r) >> 1;
if(judge(mid))
r = mid - 1;
else
l = mid + 1;
// cout << mid << endl;
}
cout << l << endl;
}