NYOJ 306 走迷宫(二分+dfs)


题目链接: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;
}

猜你喜欢

转载自blog.csdn.net/Charles_Zaqdt/article/details/80943153
今日推荐