流星雨(BFS)
题目 : 链接:https://vjudge.net/problem/POJ-3669
题意:流星雨来袭,一共有m颗陨石,每颗ti时间点的陨石砸击(xi,yi)以及其上下左右共5个点,在砸击的时刻及砸击后人都不能踏上这个点。在第一象限内,人位于原点(0,0),每次可以上下左右移动一次,找到达到安全位置的最短时间
思路:开一张数表maze初始化所有元素为inf,然后在maze标记每个格子被陨石影响的最初时间点。
人从(0,0)开始bfs,若遇到maze[nx][ny]为inf即为结束状态,输出此时的时间,否则,比较此时时刻t加上1与maze[nx][ny]的大小,若t+1更小说明能够踏上nx,ny的点,把这个点放入队列
注意:
初始原点位置:如果maze[0][0]=0说明直接被砸死,直接return,不能将其放入队列中
数组越界问题:这道题目要求陨石落下位置xi,yi是>=0并且<=300的 然而安全位置的x,y可以超过300
同样的bfs中,上下左右移动时也要判断nx,ny是否越界
避免重复将某个点放入队列,可以将这个点大小更新为t+1,这样一来以后(t+1)+1>t+1 不会再回去了(用bool数组应该也行
建议:
结构体还是写得简洁一点比较好orz
#include<iostream> #include<queue> #include<cstdio> using namespace std; const int inf = 1e5; int m; int dx[]={0,0,0,-1,1}; int dy[]={0,1,-1,0,0}; struct meteor{ int x; int y; int t; }; struct now{ int x; int y; int t; }; now pos; queue<now>q; int maze[305][305]; int bfs() { if(maze[0][0]==0) { return -1; } q.push({0,0,0}); while(!q.empty()) { pos=q.front(); if(maze[pos.x][pos.y]==inf)return pos.t; q.pop(); for(int i=1;i<=4;i++) { int nx=pos.x+dx[i]; int ny=pos.y+dy[i]; if(nx>=0&&ny>=0&&pos.t+1<maze[nx][ny]) { if(maze[nx][ny]==inf)return pos.t+1; else{ maze[nx][ny]=pos.t+1; } q.push({nx,ny,pos.t+1}); } } } return -1; } signed main() { scanf("%d",&m); for(int i=0;i<=304;i++) { for(int j=0;j<=304;j++) { maze[i][j]=inf; } } for(int i=1;i<=m;i++) { int x,y,t; scanf("%d%d%d",&x,&y,&t); for(int j=0;j<=4;j++) { if(x+dx[j]>=0&&y+dy[j]>=0&&x+dx[j]<=300&&y+dy[j]<=300)maze[x+dx[j]][y+dy[j]]=min(t,maze[x+dx[j]][y+dy[j]]); } } cout<<bfs()<<endl; return 0; }
本文作者:Ben`s code
本文链接:https://www.cnblogs.com/benscode/p/18634066
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步