题目链接
链接: P2895 [USACO08FEB] Meteor Shower S
题目描述
解题思路
广度优先搜索
题目要求贝茜找到一个永远不会被流星摧毁的地方,贝茜只能在第一象限中平行于坐标轴行动。
首先,我们可以将流星的信息存储在一个二维数组中,该数组表示每个格子被流星摧毁的时刻。初始化时,所有的格子被流星摧毁的时刻设置为无穷大。
然后,我们可以使用广度优先搜索(BFS)来找到贝茜到达安全地点的最短时间。从贝茜的初始位置开始,将初始位置加入队列中。接下来,不断从队列中取出格子,并将其周围的相邻格子加入队列中(条件是格子没有被烧焦),同时更新每个格子的最短时间。如果遇到一个格子的最短时间是无穷大,说明贝茜可以到达一个安全的位置,此时返回这个格子的最短时间。
最后,如果遍历完所有的格子后,仍然没有找到安全的位置,说明贝茜无法到达安全的地方,返回-1。
具体的实现细节如下:
定义常量M和N,分别表示流星的数量和坐标系的大小。
定义结构体node,表示一个流星的位置和时刻。
定义二维数组tim,用于存储格子被流星摧毁的时刻。
定义二维数组step,用于记录贝茜到达每个格子所需的最短时间。
定义数组dx和dy,表示贝茜每次移动的方向。
定义队列q,用于BFS。
初始化tim和step数组,将所有的格子的时刻设置为无穷大。
读入流星的信息,并更新tim数组。
从起点开始进行BFS,并更新step数组。
如果存在一个格子的最短时间是无穷大,输出这个格子的最短时间。
如果遍历完所有的格子后,仍然没有找到安全的位置,输出-1。
代码实现
#include<iostream>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef pair<int,int> PII;
const int M=50010,N=310;
struct node{
int x;
int y;
int t;
}lx[N*N];
int tim[N][N];
int step[N][N];
int dx[4]={1,0,-1,0},dy[4]={0,1,0,-1};
PII q[N*N];
bool bfs(int A,int B)
{
int hh=0,tt=0;
q[0]={A,B};
while(hh<=tt)
{
PII t=q[hh++];
for(int i=0;i<4;i++)
{
int nx=t.first+dx[i];
int ny=t.second+dy[i];
if(nx<0||ny<0) continue;
if(step[nx][ny]!=0) continue;
if(step[t.first][t.second]+1>=tim[nx][ny]) continue;
step[nx][ny]=step[t.first][t.second]+1;
q[++tt]={nx,ny};
if(tim[nx][ny]==inf){
cout<<step[nx][ny];
return true;
}
}
}
return false;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
memset(tim,inf,sizeof tim);
int m;
cin>>m;
for(int i=0;i<m;i++)
{
int lxx,lyy,ltt;
cin>>lxx>>lyy>>ltt;
lx[i]={lxx,lyy,ltt};
tim[lx[i].x][lx[i].y]=min(tim[lx[i].x][lx[i].y],lx[i].t);
for(int j=0;j<4;j++)
{
int xx=lx[i].x+dx[j];
int yy=lx[i].y+dy[j];
if(xx>=0&&xx<=300&&yy>=0&&yy<=300)
{
tim[xx][yy]=min(tim[xx][yy],lx[i].t);
}
}
}
memset(step,0,sizeof step);
if(!bfs(0,0)) cout<<"-1";
return 0;
}
总结
通过解题过程,我们学到了以下几个重要的知识点和技能:
-
广度优先搜索(BFS):在解决贝茜找到安全地点的最短时间问题中,我们使用了BFS算法来搜索贝茜可以到达的位置,并找到最短路径。BFS是一种重要的图搜索算法,能够有效地求解最短路径等问题。
-
数据结构的应用:我们使用了队列数据结构来实现BFS算法,队列能够帮助我们按照先进先出的顺序进行搜索,符合BFS算法的特点。
-
对题目建模的能力:题目描述了一个具体的场景,需要我们将问题进行抽象,并建立数学模型,将问题转化为计算机能够处理的数据结构和算法,这需要一定的抽象和建模能力。
-
编程实现的能力:通过给出的代码实现,我们学习了如何将算法思路转化为具体的C++代码实现,包括结构体定义、数组初始化、BFS算法实现等方面的知识和技能。