[C++]Meteor Shower
Meteor Shower:
巨大流星雨即将袭来。每个流星会对击中的地方以及周围(上下左右四格)造成破坏。Bessie开始时位于(0, 0)位置,并希望逃到一处不会被袭击到的地方(在第一象限内)。已知每移动一格需要1个时间单位,被流星破坏后的地方不能再进入。给出M个流星在T时刻击中的地方(X, Y),问Bessie能否逃到安全的地方,若能输出最短时间,否则输出-1。
输入格式:
- Line 1: A single integer: M
- Lines 2…M+1: Line i+1 contains three space-separated integers: Xi, Yi, and Ti
输出格式: - Line 1: The minimum time it takes Bessie to get to a safe place or -1 if it is impossible.
输入:
4
0 0 2
2 1 2
1 1 2
0 3 5
输出:
5
解题思路:先对地图进行初始化-1(不能初始化为0,因为有可能流星在时刻0就炸下来了),然后填入位置被炸的最早时间。使用bfs,如果此时时间早于位置被炸时间,则可以进入该位置。如果Bessie所在的位置为-1,就意味着不需要再移动。
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;
int m;
struct ST{
int x;
int y;
int t;
}temp,st;
int mp[310][310];
struct cmp{
bool operator() (ST a, ST b) {
return a.t > b.t;
}
};
int used[310][310];
int ne[4][2] = {0,1, 0,-1, 1,0, -1,0};
int bfs(int x, int y){
priority_queue<ST, vector<ST>, cmp> que;
st.x = x;
st.y = y;
st.t = 0;
que.push(st);
used[x][y] = 1;
while(que.size()){
st = que.top();
que.pop();
if(mp[st.x][st.y] == -1){
return st.t;
}
for(int i = 0; i<4; i++){
int nx = st.x + ne[i][0];
int ny = st.y + ne[i][1];
int nt = st.t + 1;
if(0<=nx && 0<=ny && (mp[nx][ny]==-1 || mp[nx][ny] > nt) && used[nx][ny] == 0){
temp.x = nx;
temp.y = ny;
temp.t = nt;
que.push(temp);
used[nx][ny] = 1;
}
}
}
return -1;
}
int main(){
cin>>m;
memset(mp, -1, sizeof(mp));
for(int i = 0; i<m; i++){
int x, y, t;
cin>>x>>y>>t;
if(mp[x][y] == -1)
mp[x][y] = t;
else
mp[x][y] = min(mp[x][y], t);
for(int j = 0; j<4; j++){
int nx = x+ne[j][0];
int ny = y+ne[j][1];
if( 0<=nx && 0<=ny ){
if(mp[nx][ny] == -1)
mp[nx][ny] = t;
else
mp[nx][ny] = min(mp[nx][ny], t);
}
}
}
cout<<bfs(0, 0)<<endl;
return 0;
}