题目
代码
先简单写一下吧,这道题目说多了都是泪
细节太多了
/*
本题又包含了一个时间上的维度,因此需要在判定的时候多加一个判定条件
首先不看时间,求出哪些点是永远安全的,如果bfs的时候正好到了这个点
那么就可以直接输出了
*/
#include<iostream>
#include<queue>
using namespace std;
const int N=500;//只是说陨石会砸在一片(300,300)的区域,没说农场多大,因此这里开大一点
int dx[4]={1,-1,0,0};
int dy[4]={0,0,1,-1};
typedef pair<int,int> PII;
queue <PII> q;
int M;
int yun[60000][2];//记录陨石掉落的位置
int g[N][N];//0表示不会被影响到
int step[N][N];//到达的步数
int t[N][N];//到达各坐标的时间
int go[N][N];//记录走过没有
int ch(int x){
if(x==0)
return 99999;
else
return x;
}
int bfs(){
q.push({0,0});//从第一个开始
go[0][0]=1;//标记走过
while(q.size()!=0){
auto m=q.front();
q.pop();
if(g[m.first][m.second]==0){//如果这个点永远没有危险
return step[m.first][m.second];
}
//如果有危险(但是要根据时间判断)
for(int i=0;i<4;i++){
int xx=m.first+dx[i],yy=m.second+dy[i];
if(xx>=0&&yy>=0&&go[xx][yy]==0&&step[m.first][m.second]+1<ch(t[xx][yy])){//能走,且没走过,并且在陨石到来之前
q.push({xx,yy});
step[xx][yy]=step[m.first][m.second]+1;
go[xx][yy]=1;
}
}
}
return -1;
}
int main(){
cin>>M;
int x;
int set[N][N];
//初始化各个点要注意,每个点应该算它最早开始降落的陨石时间
//并且不是他周围的要最早,它本身也要更新啊!!!我就被这个坑死了
//细节自己以后琢磨,说多了都是泪啊
for(int i=1;i<=M;i++){
cin>>yun[i][0]>>yun[i][1];
g[yun[i][0]][yun[i][1]]=1;
cin>>x;
if(set[yun[i][0]][yun[i][1]]==0||t[yun[i][0]][yun[i][1]]>=x){
set[yun[i][0]][yun[i][1]]=1;
t[yun[i][0]][yun[i][1]]=x;
}
for(int j=0;j<4;j++){
int xx=yun[i][0]+dx[j],yy=yun[i][1]+dy[j];
if(xx>=0&&yy>=0)
g[xx][yy]=1;
if(ch(t[xx][yy])>=x){
t[xx][yy]=x;
set[xx][yy]=1;
}
}//标记那些最终会被影响到的地方,这样的话,那些0的地方就永远安全了
}
int ans;
ans=bfs();
cout<<ans<<endl;
return 0;
}