(自改题目背景)
…
“天灾降临,我们并非无计可施。”
天灾降临。
天灾信使朝坐标
(
0
,
0
)
(0,0)
(0,0) 的移动城市切尔诺伯格发送紧急情报:
一共有
M
M
M 颗流星将降落到该块区域,其落点坐标为
(
X
i
,
Y
i
)
(Xi,Yi)
(Xi,Yi),会在第
T
i
Ti
Ti 个时间点落至地面。流星的力量会将它所在的位置,以及周围4个相邻的位置都化为焦土。生物无法再在这些位置上行走/生存。请尽快移入安全区域。(乌萨斯刁民,别看流星雨啦!!)
难民从第 0 0 0 个时间点开始移动,每次花费 1 s 1s 1s 向周围四格移动。如果一个位置在时刻 t t t 被流星撞击或烧焦,那么难民只能在 t t t 之前的时刻在这个位置出现。
求最少的避难时间,若无法避免,请回复 − 1 -1 −1 。默哀。
该次天灾相关数据评估:
估测流星总数:
1
<
=
M
<
=
50
,
000
1 <= M <= 50,000
1<=M<=50,000
估测落地横坐标范围:
0
<
=
X
i
<
=
300
0<=Xi<=300
0<=Xi<=300
估测落地纵坐标范围:
0
<
=
Y
i
<
=
300
0<=Yi<=300
0<=Yi<=300
估测出现时间:
0
<
=
T
i
<
=
1
,
000
0 <= Ti <= 1,000
0<=Ti<=1,000
解
BFS。
代码
#include<cstdio>
#include<iostream>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
int last[501][501], timee[501][501], m, n, top = 1, xx, yy, tt;
int fx[6] = {0, -1, +1}, fy[6] = {0,0,0,-1,+1};
struct asdf{
int x, y, t;
} startt;
queue<asdf> Q;
int main(){
freopen("meteor.in","r",stdin);
freopen("meteor.out","w",stdout);
scanf("%d", &n);
memset(last,0x7f,sizeof(last));
for(int i = 1; i <= n; ++i){
scanf("%d%d%d", &xx, &yy, &tt);
last[xx][yy] = min(last[xx][yy], tt); //这些位置被流星最先破坏的时间
last[xx+1][yy] = min(tt,last[xx+1][yy]);
last[xx][yy+1] = min(tt,last[xx][yy+1]);
if(xx > 0) last[xx-1][yy] = min(tt,last[xx-1][yy]);
if(yy > 0) last[xx][yy-1] = min(tt,last[xx][yy-1]);
}
startt = (asdf){0, 0, 0};
timee[0][0] = 0;
if(last[0][0] == last[400][400]){ //如果原先的位置就是安全的
printf("0");
fclose(stdin);
fclose(stdout);
return 0;
}
Q.push(startt);
while(!Q.empty()){
asdf d = Q.front();
Q.pop();
if(last[d.x][d.y] <= d.t) continue; //被炸
for(int i = 1; i <= 4; ++i){
int mbx = d.x + fx[i]; //目标位置
int mby = d.y + fy[i];
if(mbx >= 0 && mby >= 0) //目标位置在地图内
if(last[mbx][mby] > d.t+1 && timee[mbx][mby] == 0){ //目标位置安全
timee[mbx][mby] = timee[d.x][d.y] + 1; //处理时间
if(last[mbx][mby] == last[400][400]) { //到达安全地点
printf("%d", timee[mbx][mby]);
return 0;
}
Q.push((asdf){mbx, mby, timee[mbx][mby]});
}
}
}
printf("-1");
fclose(stdin);
fclose(stdout);
}