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
  • 相关阅读:
    第五周总结
    构建之法阅读笔记02
    第四周总结
    使用HttpClient+Json解析器爬取数据并存入数据库
    构建之法阅读笔记01
    使用Echarts+Javaweb可视化数据库中数据
    Oracle自我补充之trunc()函数使用介绍
    Oracle自我补充之OVER()函数介绍
    SpringMVC详细示例实战教程(较全开发教程)
    eclipse逆向生成hibernate的实体类(注解和配置文件)
  • 原文地址:https://www.cnblogs.com/ljy08163268/p/11738022.html
Copyright © 2011-2022 走看看