2512: 【普及/提高-】【P2895】Meteor Shower S
内存限制:128 MB
时间限制:1.000 S
评测方式:文本比较
命题人:
提交:7
解决:5
题目描述
贝茜听说一场特别的流星雨即将到来:这些流星会撞向地球,并摧毁它们所撞击的任何东西。她为自己的安全感到焦虑,发誓要找到一个安全的地方(一个永远不会被流星摧毁的地方)。
如果将牧场放入一个直角坐标系中,贝茜现在的位置是原点,并且,贝茜不能踏上一块被流星砸过的土地。
根据预报,一共有 颗流星 会坠落在农场上,其中第 颗流星会在时刻 (0<=Ti<=1000)砸在坐标为 , 的格子里。流星的力量会将它所在的格子,以及周围 个相邻的格子都化为焦土,当然贝茜也无法再在这些格子上行走。
贝茜在时刻 开始行动,它只能在第一象限中,平行于坐标轴行动,每 个时刻中,她能移动到相邻的(一般是 个)格子中的任意一个,当然目标格子要没有被烧焦才行。如果一个格子在时刻 被流星撞击或烧焦,那么贝茜只能在 之前的时刻在这个格子里出现。 贝西一开始在 。
请你计算一下,贝茜最少需要多少时间才能到达一个安全的格子。如果不可能到达输出 。
输入
共 行,第 行输入一个整数 ,接下来的 行每行输入三个整数分别为 。
输出
贝西到达安全地点所需的最短时间,如果不可能,则为 。
样例输入 复制
4
0 0 2
2 1 2
1 1 2
0 3 5
样例输出 复制
5
提示
#include<bits/stdc++.h>
using namespace std;
#define maxn 310
struct coord {
int x,y;
};
queue<coord> Q;
int ans[maxn][maxn],death[maxn][maxn]; //death表示该点被流星雨 砸中的时间
int wk[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
int main(){
int m,Ans=100000;
memset(ans,-1,sizeof(ans)); //全部赋值为-1
memset(death,0x7f,sizeof(death)); //全部赋值为一个很大的值,大约2e10
cin>>m;
for (int i=1;i<=m;i++) {
int x,y,t;
cin>>x>>y>>t;
#define MIN(x,y,t) if (x>=0&&y>=0) death[x][y]=min(death[x][y],t)
MIN(x,y,t);
for (int k=0;k<4;k++)
MIN(x+wk[k][0],y+wk[k][1],t);
//记录下流星和上下左右影响范围烧焦的时间
}
Q.push(coord{0,0}); //原点加入到队列
ans[0][0]=0;
while(!Q.empty()) {
coord u=Q.front(); //取出队首
int ux=u.x,uy=u.y;
Q.pop();
for (int k=0;k<4;k++) { //奶牛向4个方向运动
int x=ux+wk[k][0],y=uy+wk[k][1];
if (x<0||y<0||ans[x][y]!=-1||ans[ux][uy]+1>=death[x][y])
continue; /*当目标格子的最早到达时间已经比被破坏时间晚时不能更新*/
ans[x][y]=ans[ux][uy]+1;
Q.push((coord){x,y}); //扩展的结点加入队列
}
}
for (int i=0;i<=305;i++)
for (int j=0;j<=305;j++)
if (death[i][j]>1000&&ans[i][j]!=-1)
Ans=min(Ans,ans[i][j]); /*统计答案,在所有安全区域且能达到的点中找到达最早的*/
if (Ans==100000)
puts("-1");
else
printf("%d",Ans);
return 0;
}
#include<bits/stdc++.h>
using namespace std;
struct point {
int x, y, t, step, visit;
}ps[1005][1005];
int main(){
int m, x, y, t, tx, ty, dx[5] = {-1,1,0,0,0}, dy[5] = {0,0,-1,1,0};
cin >> m;
memset(ps,-1,sizeof(ps));
for(int i = 0; i < 1000; i++) {
for(int j = 0; j < 1000; j++) {
ps[i][j].x = i;
ps[i][j].y = j;
}
}
for(int i = 0; i < m; i++) {
cin >> x >> y >> t;
for (int j = 0; j < 5; j++) {
tx = x + dx[j];
ty = y + dy[j];
if (tx < 0 || ty < 0) continue;
if (ps[tx][ty].t == -1 || ps[tx][ty].t > t ) ps[tx][ty].t = t;
}
}
queue<point> q;
ps[0][0].visit = 1;
ps[0][0].step = 0;
q.push(ps[0][0]);
while (!q.empty()) {
point p=q.front();
q.pop();
for (int i = 0; i < 4; i++) {
tx=p.x + dx[i];
ty=p.y + dy[i];
if (tx < 0 || ty < 0 || ps[tx][ty].visit == 1) continue;
if (ps[tx][ty].t == -1) {
cout << p.step + 1;
return 0;
}
if (p.step + 1 < ps[tx][ty].t) {
ps[tx][ty].visit = 1;
ps[tx][ty].step = p.step + 1;
q.push(ps[tx][ty]);
}
}
}
cout << -1;
return 0;
}