题意:巨大流星雨即将袭来。每个流星会对击中的地方以及周围(上下左右四格)造成破坏。Bessie开始时位于(0, 0)位置,并希望逃到一处不会被袭击到的地方(在第一象限内)。已知每移动一格需要1个时间单位,被流星破坏后的地方不能再进入。给出M个流星在T时刻击中的地方(X, Y),问Bessie能否逃到安全的地方,若能输出最短时间,否则输出-1。
思路:初始化地图,每个点初始化无穷大,再根据输入爆炸时间不断更新最早爆炸时间,然后进行宽度搜索(BFS)。
AC代码:
#include <iostream> #include <cstdio> #include<cstring> #include <iomanip> #include <algorithm> #include <cstdlib> #include <iostream> #include<queue> using namespace std; typedef pair <int,int> p; const int INF = 100000000; //输入 int n; int xx[50000], yy[50000],tt[50000]; int mg[401][401]; //保存地图 int d[401][401]; //保存最短步数 //4个方向 int dx[4] = {-1, 1, 0, 0}; int dy[4] = {0, 0, -1, 1}; void init() { //初始化地图每个点爆炸时间为无穷大 for(int i=0;i<401;i++) fill(mg[i],mg[i]+401,INF);//二维矩阵初始化方法2 //根据输入数据更改地点爆炸时间 for(int i=0;i<n;i++) { mg[xx[i]][yy[i]]=min(tt[i],mg[xx[i]][yy[i]]); } //改动上下左右最小爆照时间 for(int j=0;j<n;j++) for(int k=0;k<4;k++) { int nx=xx[j]+dx[k]; int ny=yy[j]+dy[k]; if(nx>=0&&ny>=0) mg[nx][ny]=min(tt[j],mg[nx][ny]); } //初始化走到每一点步数为无穷大 for(int i=0;i<401;i++) fill(d[i],d[i]+401,INF); } int bfs() { if(mg[0][0]==0) return -1; queue<p>que; que.push(p(0,0)); d[0][0]=0; while(!que.empty()) { p l=que.front(); int x=l.first,y=l.second; que.pop(); if(mg[x][y]==INF) return d[x][y];//如果已到达安全位置(爆炸时间是无穷即不爆炸),返回此时所用步数 for(int i=0;i<4;i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(nx>=0&&ny>=0&&d[nx][ny]==INF&&mg[nx][ny]>d[x][y]+1) { que.push(p(nx,ny)); d[nx][ny]=d[x][y]+1; } } } return -1; } void solve() { int ans=bfs(); cout<<ans<<endl; } int main() { scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%d%d%d",&xx[i],&yy[i],&tt[i]); } init(); solve(); }