题目链接:http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=306

       这道题题意不难看懂,让我们求最小的一个路径的差值,这道题和之前写过的一道题很类似(我觉得一摸两样),用的是bfs+二分想看的可以看一下:传送门。这道题我用的是深搜,首先我们需要求出地图中的最大值和最小值,然后在最小值和最大值减去最小值这两个值里去二分差值(有点绕,仔细想一下就好),然后我们去判断这个差值能不能从左上角走到右下角,如果可以的话,我们再减小那个差值,大概思路就是这样,但是实现的时候会有好多细节问题需要去注意,细心一点就好了。需要注意的点是,地图的初始化都设为-1(不知道为什么不初始化就会wa),还有需要单独判断起点和终点是否符合那个差值。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#define maxn 105
using namespace std;
int MAP[maxn][maxn];
int vis[maxn][maxn];
int dir[4][2] = {1,0,0,1,-1,0,0,-1};
int n,Max,Min,flag;

void dfs(int L,int R,int x,int y){
  if(flag)return ;
  if(x == n-1 && y == n-1){
 flag = 1;
 return ;
  }
  for(int i=0;i<4;i++){  int X = x + dir[i][0]; int Y = y + dir[i][1]; if(MAP[X][Y] >= L && MAP[X][Y] <= R && vis[X][Y] == 0){ vis[X][Y] = 1; dfs(L,R,X,Y); } } } bool Check(int x){ for(int i=Min;i<=Max-x;i++){ if(MAP[0][0] < i || MAP[0][0] > i + x) continue;
 if(MAP[n-1][n-1] < i || MAP[n-1][n-1] > i + x) continue;
 flag = 0;
 memset(vis,0,sizeof(vis));
 vis[0][0] = 1;
 dfs(i,i+x,0,0);
 if(flag)return true;
  }
  return false;
}

int main()
{
  while(~scanf("%d",&n)){
  Max = -1;
  Min = 0x3f3f3f3f;
  memset(MAP,-1,sizeof(MAP));
  for(int i=0;i<n;i++){  for(int j=0;j<n;j++){ scanf("%d",&MAP[i][j]); if(Max < MAP[i][j])Max = MAP[i][j]; if(Min > MAP[i][j])Min = MAP[i][j];
 }
  }
  int l = 0, r = Max - Min , mid;
  while(l < r){ mid = (l + r) >> 1;
 if(Check(mid)){
 r = mid;
 }
 else l = mid + 1;
  }
  printf("%d\n",r);
}
  return 0;
}