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/