zoukankan      html  css  js  c++  java
  • leetcode 1036. 逃离大迷宫(bfs)

    题意:

    在一个 10^6 x 10^6 的网格中,每个网格块的坐标为 (x, y),其中 0 <= x, y < 10^6

    我们从源方格 source 开始出发,意图赶往目标方格 target。每次移动,我们都可以走到网格中在四个方向上相邻的方格,只要该方格不在给出的封锁列表 blocked 上。

    只有在可以通过一系列的移动到达目标方格时才返回 true。否则,返回 false

    示例 1:

    输入:blocked = [[0,1],[1,0]], source = [0,0], target = [0,2]
    输出:false
    解释:
    从源方格无法到达目标方格,因为我们无法在网格中移动。

    示例 2:

    输入:blocked = [], source = [0,0], target = [999999,999999]
    输出:true
    解释:
    因为没有方格被封锁,所以一定可以到达目标方格。

    思路:

    • 对两个点分别查找两遍看是否被困住在障碍物间。找到则表示true即使被困住也是两个都被困住。
    • 第一遍没找到且队列如果为空则证明被困住了返回false.没别困住则调换从target找source
    • 看target是否被困住。如果两个都没被困住return true;
    • 一共只有最多blocks的长度(记为len)个障碍,那么他至多能封堵len*(len-1)大小的区域。以source和target分别为起点,只要能够抵达任意一个dx或者dy大于等于len的点(棋盘是足够大的),意味着就能离开封锁区域。

      具体为什么最大是len*(len-1),参考下图:

     1 #define mk(a,b) make_pair(a,b)
     2 const int N=1e6;
     3 class Solution {
     4 public:
     5     int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
     6     map<pair<int,int>,bool>mp;
     7     bool sol(int x,int y,int sx,int sy,int sz){
     8         map<pair<int,int>,bool>vis;
     9         queue<pair<int,int>>q;
    10         q.push(mk(x,y));
    11         vis[mk(x,y)]=true;
    12         int maxn=sz*(sz-1)/2,cnt=1;
    13         while(!q.empty()&&cnt<=maxn){
    14             pair it=q.front(); q.pop();
    15             if(it==mk(sx,sy))return true;
    16             for(int i=0;i<4;i++){
    17                 int lx=it.first+dir[i][0],ly=it.second+dir[i][1];
    18                 if(lx>=0&&lx<N&&ly>=0&&ly<N&&vis.find(mk(lx,ly))==vis.end()&&mp.find(mk(lx,ly))==mp.end()){
    19                     vis[mk(lx,ly)]=true;
    20                     q.push(mk(lx,ly));
    21                     cnt++;
    22                 }
    23             }
    24         }
    25         return !q.empty();//为空说明被困住
    26     }
    27     bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& source, vector<int>& target) {
    28         int n=blocked.size();
    29         for(int i=0;i<n;i++)mp[mk(blocked[i][0],blocked[i][1])]=true;
    30         return sol(source[0],source[1],target[0],target[1],n)&sol(target[0],target[1],source[0],source[1],n);
    31         
    32     }
    33 };
    View Code
  • 相关阅读:
    VSCode配置Python开发环境
    图像特征——边缘
    关于相机内参中的焦距fx和fy
    摄影变换和仿射变换
    为什么要引入齐次坐标
    链表一
    从小问题看懂链表
    类与对象
    排序一
    数组
  • 原文地址:https://www.cnblogs.com/ljy08163268/p/11738022.html
Copyright © 2011-2022 走看看