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
这一题还是很有意思的。

posted @ 2019-09-17 20:16  于老师的父亲王老爷子  阅读(13)  评论(0编辑  收藏  举报