1036. Escape a Large Maze
这一题很有意思,需要注意的点不太一样。
首先想到的是dfs,但是由于格子数太多,肯定会超时,所以否决。
然后自己观察到要想把两个点分开,只有两种情况:
1.阻塞的格子和边上的格子一起形成一个封闭的空间,两个点一个在里头,一个在外头
2.阻塞的格子自己就形成一个封闭的空间,一个在里头,一个在外头。
之后就不知道怎么做了。
然后看了评论区,才知道:
阻塞的格子不超过200个这是一个最重要的条件。有了它我们就知道阻塞的格子最多可以封闭的空间有多大,只要我们从一个格子出发,他能访问的位置不止这么多个,就说明它没有被封闭。对源和目标都进行这样的判断,如果都没有被封闭,就可以达到。
class Solution {
public:
bool isEscapePossible(vector<vector<int>>& blocked, vector<int>& source, vector<int>& target) {
set<pair<int, int>> blockedSet;
for (auto& vec : blocked)
blockedSet.insert(make_pair(vec[0], vec[1]));
return canVisited(blockedSet, make_pair(source[0], source[1]), make_pair(target[0], target[1])) && canVisited(blockedSet, make_pair(target[0], target[1]), make_pair(source[0], source[1]));
}
private:
int MAX_VISIT = 20000;
vector<vector<int>> dirs{{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
bool canVisited(set<pair<int, int>>& blockedSet, pair<int, int> source, pair<int, int> target) {
set<pair<int, int>> visited;
dfs(blockedSet, visited, source, target);
return visited.size() >= MAX_VISIT || visited.find(target) != visited.end();
}
void dfs(set<pair<int, int>>& blockedSet, set<pair<int, int>>& visited, pair<int, int> curr, const pair<int, int>& target) {
if (curr.first < 0 || curr.first >= 1e6 || curr.second < 0 || curr.second >= 1e6 || blockedSet.find(curr) != blockedSet.end())
return;
if (visited.find(curr) != visited.end())
return;
visited.insert(curr);
if (visited.size() >= MAX_VISIT || curr == target)
return;
for (auto& dir : dirs)
dfs(blockedSet, visited, make_pair(curr.first+dir[0], curr.second+dir[1]), target);
}
};
现在问题来了,这个20000是怎么得到的?
摘自评论区:
1+2+3+4+5+…+198+199=(1+199)*199/2=19900
这一题还是很有意思的。