789. 逃脱阻碍者 中等 曼哈顿距离
2021.08.22 签到题

个人思路:朴素BFS
- 对于玩家而言,每次往集合A中加入上下左右四个点,并删去该点,这里我认为玩家不动是没啥意义的,加入的点表示走n步后,当前玩家可能所在的点位。
- 对于阻碍者而言,每次往另一个集合B中加入上下左右四个点,保留当前的点,相当于得到了一个区域范围。
- 玩家当前的位置不能在区域范围内,如果某个点在阻碍者集合B中,删去该点,即求
A-(A∩B)。- 如果
A-(A∩B)为空时,表示不能逃出。 - 如果
A-(A∩B)中有终点,表示逃出。
- 如果
动手实现试试。
class Solution {
public:
struct node{
int x;
int y;
node(int _x,int _y):x(_x),y(_y){}
bool operator < (const node & temp)const{
if(x==temp.x)return y<temp.y;
else return x<temp.x;
}
};
int X[4]={0,0,1,-1};
int Y[4]={1,-1,0,0};
bool escapeGhosts(vector<vector<int> >& ghosts, vector<int>& target) {
set<node> A;
set<node> B;
for(int i=0;i<ghosts.size();i++){
B.insert(node(ghosts[i][0],ghosts[i][1]));
}
A.insert(node(0,0));
if(target[0]==0&target[1]==0)return true;
while(1){
set<node> temp_A;
for(set<node>::iterator iter=A.begin();iter!=A.end();iter++){
for(int i=0;i<4;i++){
temp_A.insert(node(iter->x+X[i],iter->y+Y[i]));
}
}
set<node> temp_B;
for(set<node>::iterator iter=B.begin();iter!=B.end();iter++){
for(int i=0;i<4;i++){
temp_B.insert(node(iter->x+X[i],iter->y+Y[i]));
}
}
B.insert(temp_B.begin(),temp_B.end());
set<node> temp1,temp2;
set_intersection(temp_A.begin(),temp_A.end(),B.begin(),B.end(),inserter(temp1,temp1.begin()));
set_difference(temp_A.begin(),temp_A.end(),temp1.begin(),temp1.end(),inserter(temp2,temp2.begin()));
A=temp2;
if(A.size()==0)return false;
else if(A.find(node(target[0],target[1]))!=A.end())return true;
if(B.find(node(target[0],target[1]))!=B.end())return false;
}
}
};
尬住了,简单的几个测试用例都通过了,但是提交时,有些用力超时了。虽然尝试做之前就估计这种笨笨的模拟会超时,难受。
知识小结:
- set容器 添加自定义的 数据类型时,要重载 < 且要声明const
- set求差集:set_difference()
- set求交集:set_intersection()
- set求并集:set_union()
正确思路: 曼哈顿距离
我写的比较蠢,想的是玩家在达到终点前是否会被抓到,这道题本身不需要更游戏一样展现出来,只要判断可能性即可,看了下别人的题解,既然都是一起行动的,只要玩家距离终点更近,就能跑掉,这个距离即曼哈顿距离。
自己简单写一下:
bool escapeGhosts(vector<vector<int> >& ghosts, vector<int>& target) {
int p_dis=abs(target[0])+abs(target[1]);
for(int i=0;i<ghosts.size();i++){
int temp = abs(target[0]-ghosts[i][0])+abs(target[1]-ghosts[i][1]);
if(temp<=p_dis)return false;
}
return true;
}
尬住了,才这么点代码,有时候,思路真的很重要啊,不过模拟怪物抓玩家这个过程也蛮有意思的。

浙公网安备 33010602011771号