In a 1 million by 1 million grid, the coordinates of each grid square are (x, y)
with 0 <= x, y < 10^6
.
We start at the source
square and want to reach the target
square. Each move, we can walk to a 4-directionally adjacent square in the grid that isn't in the given list of blocked
squares.
Return true
if and only if it is possible to reach the target square through a sequence of moves.
Example 1:
Input: blocked = [[0,1],[1,0]], source = [0,0], target = [0,2] Output: false Explanation: The target square is inaccessible starting from the source square, because we can't walk outside the grid.
Example 2:
Input: blocked = [], source = [0,0], target = [999999,999999] Output: true Explanation: Because there are no blocked cells, it's possible to reach the target square.
Note:
0 <= blocked.length <= 200
blocked[i].length == 2
0 <= blocked[i][j] < 10^6
source.length == target.length == 2
0 <= source[i][j], target[i][j] < 10^6
source != target
struct hash_pair
{
size_t operator()(const pair<int , int>& p) const
{
auto hash1 = hash<int>{}(p.first) ;
auto hash2 = hash<int>{}(p.second) ;
return hash1 ^ hash2 ;
}
};
class Solution {
public:
bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& source, vector<int>& target)
{
if(blocked.empty()) return true ;
unordered_set<pair<int , int> , hash_pair> blockset ;
for(auto b : blocked)
blockset.insert({b[0] , b[1]}) ;
return search(blockset , source , target) && search(blockset , target , source) ;
}
private:
vector<int> dir = {0 , -1 , 0 , 1 , 0} ;
bool search(unordered_set<pair<int , int> , hash_pair>& blockset , vector<int>& source , vector<int>& target)
{
queue<pair<int , int>> q ;
q.push({source[0] , source[1]}) ;
unordered_set<pair<int , int> , hash_pair> visited ;
visited.insert({source[0] , source[1]}) ;
int area = 1 ;
while(!q.empty())
{
pair<int , int> squa = q.front() ;
q.pop() ;
if(area >= 20000) return true ;
for(int i = 0 ; i < 4 ; ++i)
{
int new_x = squa.first + dir[i] , new_y = squa.second + dir[i + 1] ;
if(new_x < 0 || new_x >= 1000000 || new_y < 0 || new_y >= 1000000 || blockset.count({new_x , new_y}) || visited.count({new_x , new_y})) continue ;
if(new_x == target[0] && new_y == target[1]) return true ;
q.push({new_x , new_y}) ;
visited.insert({new_x , new_y}) ;
area++ ;
}
}
return false ;
}
};