leetcode 6054. 逃离火灾 思维 bfs
Posted goto_1600
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode 6054. 逃离火灾 思维 bfs相关的知识,希望对你有一定的参考价值。
思路:
当然可以二分 + bfs 复杂度
O
(
l
o
g
(
n
∗
m
)
n
∗
m
)
O(log(n*m)n*m)
O(log(n∗m)n∗m) 这个比较好想,但如何进一步优化,我们可以逆向考虑,从终点倒着找到离终点最近的火和最近的人的距离,当然如果火比人先到那肯定就是-1,如果找不到火就是1e9,然后就判断最近的火和人的位置关系,因为右下角只有两种转移位置,一种是上方一种是左方,有个比较有意思的性质,到两个方向的人的差要么是0,要么是1,而火的差距可以取到0,1,2,大家可以思考一下为什么?
如果最近的火到这两个位置都是最小值,那么人肯定要提早走一次,答案要减1,如果人到上侧和左侧是最小值,那么人可以选择一个地方走避免和火走同一个位置不用减1,如果上两种情况都不是,那么判断火和人是否走唯一方向就可以了,如果是同个方向就减1。复杂度
O
(
3
∗
n
∗
m
)
O(3*n*m)
O(3∗n∗m)
int dist[310][310];
int maxv[310][310];
int st[310][310];
class Solution
public:
int maximumMinutes(vector<vector<int>>& grid)
int n=grid.size();
int m=grid[0].size();
queue<pair<int,int>>qq;
int dx[]=0,0,1,-1;
int dy[]=1,-1,0,0;
auto solve = [&](int ex,int ey)
int fire=0x3f3f3f3f;
int human=0x3f3f3f3f;
queue<pair<int,int>>q;
if(grid[ex][ey]==2) return -1;
q.push(ex,ey);
memset(st,-1,sizeof st);
st[ex][ey]=0;
while(q.size())
auto tt=q.front();
q.pop();
if(fire==0x3f3f3f3f && grid[tt.first][tt.second]==1)
fire=st[tt.first][tt.second];
if(human==0x3f3f3f3f && tt.first==0 && tt.second==0)
human=st[tt.first][tt.second];
for(int i=0;i<4;i++)
int tx=tt.first+dx[i];
int ty=tt.second+dy[i];
if(tx>=n || ty>=m || tx<0 || ty<0 || grid[tx][ty]==2 || st[tx][ty]!=-1) continue;
st[tx][ty]=st[tt.first][tt.second]+1;
q.push(tx,ty);
if(human==0x3f3f3f3f) return -1;
if(fire==0x3f3f3f3f) return (int)1e9;
return fire-human;
;
int xx=solve(n-1,m-1);
if(xx==-1) return -1;
if(xx==1e9) return 1e9;
int a=solve(n-2,m-1);
int b=solve(n-1,m-2);
if(max(a,b)==xx) xx--;
if(xx<0) xx=-1;
return xx;
;
以上是关于leetcode 6054. 逃离火灾 思维 bfs的主要内容,如果未能解决你的问题,请参考以下文章