题目链接:点击打开链接
题意:
M个陨石会在某个时间砸向地图某点,摧毁该点及其上下左右总共五个格子,也就是在这个时间以后这些
格子就不能通过了,问主人公从(0,0)开始最少需要多少时间能到达安全的地方(也就是一直不会被摧
毁的地方)
先初始化所以格子的崩塌时间为INF(无限大),然后预处理出所有的时间。
再BFS,如果没越界、没访问过而且 到达这点的时间<陨石摧毁这点的时间,就可以走。
将这样的点入队列,如果从队列取出的点的 崩塌时间为无穷大,则返回到这点的时间,即为结果。
比赛的时候 思路没理清,想把崩塌时间和BFS时的到达时间混在一起,只用一个vis[][]处理修改
其值。这样不好弄。
注意点:崩塌点上下左右5个点可能超过了300的范围。所以边界判断上界要稍微大点取。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
struct node
{
int x,y;
int t;
}h;
int bt[310][310];
bool vis[310][310];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
queue<node> q;
int bfs()
{
while(!q.empty())
q.pop();
h.x=0,h.y=0;
h.t=0;
q.push(h);
vis[h.x][h.y]=true;
node cur,next;
while(!q.empty())
{
cur=q.front();
q.pop();
if(bt[cur.x][cur.y]==INF)
return cur.t;
for(int i=0;i<4;i++)
{
next.x=cur.x+dx[i];
next.y=cur.y+dy[i];
next.t=cur.t+1;
if(next.x>=0 && next.x<305 && next.y>=0 && next.y<305)
{
if(!vis[next.x][next.y] && bt[next.x][next.y]>next.t)
{
q.push(next);
vis[next.x][next.y]=true;
}
}
}
}
return -1;
}
int main()
{
int m,x,y,t;
while(scanf("%d",&m)!=EOF)
{
memset(bt,INF,sizeof(bt));
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&t);
if(bt[x][y]>t)
bt[x][y]=t;
for(int k=0;k<4;k++)
{
int xx=x+dx[k];
int yy=y+dy[k];
if(xx>=0 && xx<305 && yy>=0 && yy<305 && bt[xx][yy]>t)
bt[xx][yy]=t;
}
}
memset(vis,0,sizeof(vis));
int flag=bfs();
printf("%d\n",flag);
}
return 0;
}