题目
题目描述
贝茜听说一场非同寻常的流星雨即将来临。报道说,这些流星会撞向地球,摧毁它们击中的任何东西。由于担心自己的安全,她发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。她目前正在坐标平面的原点放牧,并希望移动到一个新的,更安全的位置,同时避免被流星摧毁。
报道称,M颗流星(1≤M≤50,000)将撞击,流星i将撞击点(Xi,Yi)(0 ≤ Xi ≤300;0 ≤ Yi ≤ 300)在Ti(0 ≤ Ti ≤1,000)。每颗流星都会破坏它所撞击的点以及四个直线相邻的晶格点。
Bessie 在时间 0 离开原点,并且可以在第一象限中以每秒一个距离单位的速度平行于轴,到达尚未被流星破坏的任何相邻直线点(通常为 4 个)。她不能在任何时候都位于大于或等于该点被摧毁的时间)。
确定贝茜到达安全地点所需的最短时间。
输入格式
* 第 1 行:单个整数:M
* 2..M+1 行:行 i+1 包含三个空格分隔的整数:Xi、Yi 和 Ti
输出格式
*第1行:Bessie到达安全地点所需的最短时间,如果不可能,则为-1。
输入输出样例
输入 #1复制
4 0 0 2 2 1 2 1 1 2 0 3 5
输出 #1复制
5
题解
1.首先明确,这是一个BFS求最短路径的问题。
2.四个数组,标记数组,方向数组(4个方向上下左右),地图数组,队列数组。
3.关于地图:关于每颗流星都会破坏它所撞击的点以及四个直线相邻的晶格点。我们可以在输入的时候,把四个直线相邻的点以及输入的点的地图数组的标记为最小时间,最小时间的处理,判断这个点是否被改变,如果没有被改变,就把地图数组改变成当前时间,如果被改变过,就取改变的最小时间。
4.向四个方向不断遍历,直到找到最后的安全点(结束条件)地图数组值没有改变的点,用一个变量来判断,是否找到安全点。
5.关于界线问题,被这个坑到了,界线:x,y可以超过300,但是必须要大于等于0。
代码如下
#include"stdio.h"
#include"string.h"
int min(int a,int b)
{
if(a>=b)
return b;
else return a;
}
struct node
{
int x;
int y;
int step;
};
int main()
{
int n,m,xx,yy,time,i,sign=0,x1,y1;
int s[400][400];
int book[400][400];
int fx[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct node d[50001];
for(n=0;n<=302;n++)
{
for(i=0;i<=302;i++)
{
s[n][i]=-2;
}
}
scanf("%d",&m);
for(n=0;n<m;n++)
{
scanf("%d %d %d",&xx,&yy,&time);
if(s[xx][yy]==-2)
s[xx][yy]=time;
else if(s[xx][yy]!=-2)
{
s[xx][yy]=min(s[xx][yy],time);
}
for(i=0;i<4;i++)
{
x1=xx+fx[i][0];
y1=yy+fx[i][1];
if(s[x1][y1]==-2)
s[x1][y1]=time;
else if(s[x1][y1]!=-2)
s[x1][y1]=min(s[x1][y1],time);
}
}
int head,tail;
head=tail=1;
d[tail].x=0;
d[tail].y=0;
d[tail].step=0;
book[0][0]=1;
tail++;
while(head<tail)
{
// printf("%d %d %d %d\n",d[head].x,d[head].y,s[d[head].x][d[head].y],d[head].step);
if(s[d[head].x][d[head].y]==-2)
{
sign=1;
break;
}
for(i=0;i<4;i++)
{
xx=d[head].x+fx[i][0];
yy=d[head].y+fx[i][1];
if(book[xx][yy]==0&&xx>=0&&yy>=0&&(s[xx][yy]==-2||s[xx][yy]>d[head].step+1))
{
book[xx][yy]=1;
d[tail].x=xx;
d[tail].y=yy;
d[tail].step=d[head].step+1;
tail++;
}
}
head++;
}
if(sign==1)
{
printf("%d",d[head].step);
}
else
printf("-1");
return 0;
}