LeetCode----789. 逃脱阻碍者 规律和模拟

https://leetcode-cn.com/problems/escape-the-ghosts/

你在进行一个简化版的吃豆人游戏。你从 (0, 0) 点开始出发,你的目的地是 (target[0], target[1]) 。地图上有一些阻碍者,第 i 个阻碍者从 (ghosts[i][0], ghosts[i][1]) 出发。

每一回合,你和阻碍者们*可以*同时向东,西,南,北四个方向移动,每次可以移动到距离原位置1个单位的新位置。

如果你可以在任何阻碍者抓住你之前到达目的地(阻碍者可以采取任意行动方式),则被视为逃脱成功。如果你和阻碍者同时到达了一个位置(包括目的地)都不算是逃脱成功。

当且仅当你有可能成功逃脱时,输出 True。

示例 1:
输入: 
ghosts = [[1, 0], [0, 3]]
target = [0, 1]
输出:true
解释:
你可以直接一步到达目的地(0,1),在(1, 0)或者(0, 3)位置的阻碍者都不可能抓住你。 
示例 2:
输入: 
ghosts = [[1, 0]]
target = [2, 0]
输出:false
解释:
你需要走到位于(2, 0)的目的地,但是在(1, 0)的阻碍者位于你和目的地之间。 
示例 3:
输入: 
ghosts = [[2, 0]]
target = [1, 0]
输出:false
解释:
阻碍者可以和你同时达到目的地。 

说明:

  • 所有的点的坐标值的绝对值 <= 10000
  • 阻碍者的数量不会超过 100

非常有趣

我的算法: 让人和鬼以起始点开始扩展,如果人无路可走,那么鬼胜利,如果人先找到,人胜利。有点模拟的意思。

class Solution {
    public:
        typedef struct
        {
            int x,y;
        } node;
        queue<node> g,p;
        int xx[4]= {0,0,1,-1};
        int yy[4]= {1,-1,0,0};
        node t,tar,t2;
        int n=0;
        int m=0;
        //int vist[10000][10000];
        set<int> iset;
        bool res=false,isstop=false;
        bool escapeGhosts(vector<vector<int>>& ghosts, vector<int>& target) {

            t.x=0+10000;
            t.y=0+10000;
            p.push(t);

            tar.x=target[0]+10000;
            n=max(n,tar.x);
            tar.y=target[1]+10000;
            m=max(m,tar.y);

            if(t.x==tar.x&&t.y==tar.y) return true;

            for(int i=0; i<ghosts.size(); i++)
            {
                t.x=ghosts[i][0]+10000;
                t.y=ghosts[i][1]+10000;
                m=max(m,t.y);
                n=max(n,t.x);
                g.push(t);
            }

            n=n+10;
            m=m+10;

            while(p.size()&&!isstop)
            {
                bfs(0); //ghost
                bfs(1); //people
                //cout<<p.size()<<endl;
            }
            return res;
        }

        void bfs(int flag)
        {
            if(isstop) return;
            if(flag==0)  //ghost
            {
                int num=g.size();
                while(num--)
                {
                    t=g.front();
                    g.pop();
                    //cout<<t.x<<" "<<t.y<<endl;
                    for(int i=0; i<4; i++)
                    {
                        t2.x=t.x+xx[i];
                        t2.y=t.y+yy[i];
                        if(t2.x>=0&&t2.x<n&&t2.y>=0&&t2.y<m)
                        {
                            if(t2.x==tar.x&&t2.y==tar.y)
                            {
                                isstop=true; //老巢被占了
                            }
                            if(!iset.count(t2.x*m+t2.y))
                            {
                                g.push(t2);
                                iset.insert(t2.x*m+t2.y);
                            }
                        }
                    }
                }
            }
            else
            {
                int num=p.size();
                while(num--)
                {
                    t=p.front();
                    p.pop();
                    // cout<<t.x<<" "<<t.y<<endl;
                    for(int i=0; i<4; i++)
                    {
                        t2.x=t.x+xx[i];
                        t2.y=t.y+yy[i];
                        if(t2.x>=0&&t2.x<n&&t2.y>=0&&t2.y<m)
                        {
                            if(t2.x==tar.x&&t2.y==tar.y)
                            {
                                isstop=true;
                                res=true;
                            }
                            if(!iset.count(t2.x*m+t2.y))
                            {
                                p.push(t2);
                                iset.insert(t2.x*m+t2.y);
                            }
                        }
                    }
                }
            }
        }
};

大牛的答案

画个抽象的示意图来解释下为神马直接比较距离即可 A表示起点 B表示鬼魂?的位置 目的地为C 如果鬼魂?要在中间拦截 AC上必须有一点D 使得AD = DB 通过三角不等式 AC = AD + DC = DB + DC >= BC 如果鬼魂可以拦截到 那么鬼魂?最好的做法就是在终点等着 而不是去中间拦截 上面假设选择的是最短路径 乱走的话 相信鬼魂?会笑的更开心

/**
 *
 *          C
 *         /  \
 *        /    \
 *       /      \
 *      /        \
 *     /   \D     \
 *    /      \     \
 *   /         \    \
 *  /            \   \
 * A               \
 *                     B
 *
 * */
class Solution {
    public boolean escapeGhosts(int[][] ghosts, int[] target) {
        int max=100;
        int disMe,disTur;
        disMe=this.distance(new int[]{0,0},target);
        for(int i=0;i<ghosts.length&&i<max;i++){
            disTur=this.distance(ghosts[i],target);
            if(disTur<=disMe)
                return false;
        }
        return true;
            
    }
    private  int distance(int [] start,int [] target){
        return Math.abs(target[0]-start[0])+Math.abs(target[1]-start[1]);
    }
}

 转自 https://leetcode-cn.com/problems/escape-the-ghosts/comments/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LeetCode-Editor是一种在线编码工具,它提供了一个用户友好的界面编写和运行代码。在使用LeetCode-Editor时,有时候会出现乱码的问题。 乱码的原因可能是由于编码格式不兼容或者编码错误导致的。在这种情况下,我们可以尝试以下几种解决方法: 1. 检查文件编码格式:首先,我们可以检查所编辑的文件的编码格式。通常来说,常用的编码格式有UTF-8和ASCII等。我们可以将编码格式更改为正确的格式。在LeetCode-Editor中,可以通过界面设置或编辑器设置来更改编码格式。 2. 使用正确的字符集:如果乱码是由于使用了不同的字符集导致的,我们可以尝试更改使用正确的字符集。常见的字符集如Unicode或者UTF-8等。在LeetCode-Editor中,可以在编辑器中选择正确的字符集。 3. 使用合适的编辑器:有时候,乱码问题可能与LeetCode-Editor自身相关。我们可以尝试使用其他编码工具,如Text Editor、Sublime Text或者IDE,看是否能够解决乱码问题。 4. 查找特殊字符:如果乱码问题只出现在某些特殊字符上,我们可以尝试找到并替换这些字符。通过仔细检查代码,我们可以找到导致乱码的特定字符,并进行修正或替换。 总之,解决LeetCode-Editor乱码问题的方法有很多。根据具体情况,我们可以尝试更改文件编码格式、使用正确的字符集、更换编辑器或者查找并替换特殊字符等方法来解决这个问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值