[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;
}