描述 Description | |||
贝茜听说了一个骇人听闻的消息:一场流星雨即将袭击整个农场,由于流星 体积过大,它们无法在撞击到地面前燃烧殆尽,届时将会对它撞到的一切东西 造成毁灭性的打击。很自然地,贝茜开始担心自己的安全问题。以FJ牧场中最 聪明的奶牛的名誉起誓,她一定要在被流星砸到前,到达一个安全的地方(也就 是说,一块不会被任何流星砸到的土地)。如果将牧场放入一个直角坐标系中, 贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。 根据预报,一共有M颗流星(1 <= M <= 50,000)会坠落在农场上,其中第i颗 流星会在时刻T_i (0 <= T_i <= 1,000)砸在坐标为(X_i, Y_i) (0 <= X_i <= 300;0 <= Y_i <= 300)的格子里。流星的力量会将它所在的格子 ,以及周围4个相邻的格子都化为焦土,当然贝茜也无法再在这些格子上行走。 贝茜在时刻0开始行动,它只能在第一象限中,平行于坐标轴行动,每1个时刻中, ,她能移动到相邻的(一般是4个) 格子中的任意一个,当然目标格子要没有被烧焦才行。如果一个格子在时刻t被 流星撞击或烧焦,那么贝茜只能在t之前的时刻在这个格子里出现。 请你计算一下,贝茜最少需要多少时间才能到达一个安全的格子。 | |||
输入格式 Input Format | |||
* 第1行: 1个正整数:M * 第2..M+1行: 第i+1行为3个用空格隔开的整数:X_i,Y_i,以及T_i | |||
输出格式 Output Format | |||
第1行: 输出1个整数,即贝茜逃生所花的最少时间。如果贝茜无论如何都无法 在流星雨中存活下来,输出-1 |
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<queue>
#include<cstring>
using namespace std;
int M,Q[90086][3],Smap[320][320];//Q为队列数组,Smap为地图矩阵
int xx[5]={0,-1,1,0,0},yy[5]={0,0,0,-1,1};
struct da
{
int xi,yi,ti;
}map[50086];//记录流星的落点及时间
void init()
{
cin>>M;
for(int i=1;i<=M;i++)
scanf("%d%d%d",&map[i].xi,&map[i].yi,&map[i].ti);
}
bool mycmp(da a,da b)
{return a.ti<b.ti;}//让流星按落地时间升序排列
int main()
{
init();
sort(map+1,map+M+1,mycmp);
memset(Smap,0,sizeof(Smap));
memset(Q,-1,sizeof(Q));
Q[1][1]=0,Q[1][2]=0;int FSpoint=1,Ttime=0,head=1,tail=2;
while(map[FSpoint].ti==Ttime)//模拟当前时刻Ttime流星砸落过程
{
Smap[map[FSpoint].xi][map[FSpoint].yi]=-1;
for(int i=1;i<=4;i++)
if(map[FSpoint].xi+xx[i]>=0&&map[FSpoint].xi+xx[i]<=300)
if(map[FSpoint].yi+yy[i]>=0&&map[FSpoint].yi+yy[i]<=300)
Smap[map[FSpoint].xi+xx[i]][map[FSpoint].yi+yy[i]]=-1;
FSpoint++;
}
Ttime=1;
while(Ttime<=map[M].ti)//按时间每过1个单位循环
{
while(map[FSpoint].ti==Ttime)//模拟当前时刻Ttime流星砸落过程
{
Smap[map[FSpoint].xi][map[FSpoint].yi]=-1;
for(int i=1;i<=4;i++)
if(map[FSpoint].xi+xx[i]>=0&&map[FSpoint].xi+xx[i]<=300)
if(map[FSpoint].yi+yy[i]>=0&&map[FSpoint].yi+yy[i]<=300)
Smap[map[FSpoint].xi+xx[i]][map[FSpoint].yi+yy[i]]=-1;
FSpoint++;
}
//从上一层可以行走的点拓展出本次的时间点人可以走到的位置
int ansnow=tail;
for(int i=head;i<tail;i++)
{
for(int j=1;j<=4;j++)
if(Q[i][1]+xx[j]>=0&&Q[i][1]+xx[j]<=310)
if(Q[i][2]+yy[j]>=0&&Q[i][2]+yy[j]<=310)
if(Smap[Q[i][1]+xx[j]][Q[i][2]+yy[j]]==0&&(Q[i][1]+xx[j]!=0||Q[i][2]+yy[j]!=0))
{
Q[ansnow][1]=Q[i][1]+xx[j];
Q[ansnow++][2]=Q[i][2]+yy[j];
Smap[Q[i][1]+xx[j]][Q[i][2]+yy[j]]=Ttime;
}
}head=tail;tail=ansnow;
Ttime++;//时间+1,队头与队尾向后“一层”
}//==================找逃生时间最小值并判断是否输出-1==========
if(Smap[0][0]==0)
{cout<<0<<endl;return 0;}
int anss=21478953,qqqqq=0;
for(int i=0;i<=310;i++)
for(int j=0;j<=310;j++)
if(Smap[i][j]!=-1&&Smap[i][j]!=0)
anss=min(anss,Smap[i][j]),qqqqq=1;
if(!qqqqq) cout<<-1<<endl;
else cout<<anss<<endl;
return 0;
}