题意翻译

输入输出样例
输入 #1
4
0 0 2
2 1 2
1 1 2
0 3 5
输出 #1
5
分析:
这道题很明显是一道BFS搜索题。但是有很多注意事项
- 坐标不能小于0,但可以大于300
- 一个位置被流星烧焦的时间按最早被烧焦的时间算。
- 出不去要输出-1
思路:
使用一个二维数组存储地图,mp[i][j]数组记录当前位置(i,j)被烧焦的最早时间,对于一个流星坠落的位置,把它的上下左右四个位置全部更新为最早被烧焦的时间。
有了这个二维数组,在BFS的过程中,对于一个从队列中取出的位置(temp.x,temp.y)只需要将该点上下左右四个位置中合法的位置加入队列即可。
合法的位置(ax,ay)条件为:
- ax>=0&&ay>=0
- vis[ax][ay]==0(该位置没有被走过)
- temp.T+1<mp[ax][ay] 或者 (ax,ay)不会被砸到
AC代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 550;
int mp[maxn][maxn];
int dx[]= {-1,1,0,0};
int dy[]= {0,0,-1,1};
typedef struct node
{
int x,y;
int T;
} Node;
int vis[maxn][maxn];
void bfs()
{
queue<Node>q;
q.push({0,0,0});
while(!q.empty())
{
Node temp = q.front();
q.pop();
//如果当前位置是一个安全位置,就终止循环。
if(mp[temp.x][temp.y]==-1)
{
cout<<temp.T<<endl;
return ;
}
for(int i = 0; i<4; i++)
{
int ax = temp.x+dx[i];
int ay = temp.y+dy[i];
//如果这个点合法并且没有走过,且在下一秒不会被流星砸到就把这个点放入队列
if(ax>=0&&ay>=0&&!vis[ax][ay]&&(temp.T+1<mp[ax][ay]||mp[ax][ay]==-1))
{
vis[ax][ay]=1;
q.push({ax,ay,temp.T+1});
}
}
}
//没有找到安全的位置
cout<<-1<<endl;
}
void init(int x,int y,int t)
{
for(int j = 0; j<4; j++)
{
int ax = x+dx[j];
int ay = y+dy[j];
if(ax>=0&&ay>=0)
{
//更新当前位置被流星烧焦的时间
if(mp[ax][ay]!=-1)
mp[ax][ay]=min(mp[ax][ay],t);
else
mp[ax][ay]=t;
}
}
}
int main()
{
int n,x,y,t;
cin>>n;
memset(mp,-1,sizeof(mp));
//初始化地图
for(int i = 1; i<=n; i++)
{
cin>>x>>y>>t;
//
if(mp[x][y]!=-1)
{
mp[x][y]=min(t,mp[x][y]);
}
else
{
mp[x][y]=t;
}
init(x,y,t);
}
bfs();
return 0;
}
这篇博客介绍了一道BFS搜索题,涉及到二维数组、坐标限制和BFS搜索策略。题目要求找出在流星雨烧焦的地图中,是否存在安全区域(不会被后续流星烧到的地方)。博主给出了详细的思路解析,包括如何更新地图、合法位置判断以及BFS过程,并提供了完整的AC代码实现。
924

被折叠的 条评论
为什么被折叠?



