题目解析:仍然是走过的点可以再走,所以标记数组vis[]记录的是经过该点的最大(而不是最小)的爆炸时间。
代码如下;
#include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std; int map[10][10]; int vis[10][10]; int m,n; int begin_x,begin_y,end_x,end_y; int dx[5]={0,0,1,-1}; int dy[5]={1,-1,0,0}; struct node { int x; int y; int time; int bomb; }; void bfs() { memset(vis,0,sizeof(vis)); node node1,node2; queue<node>q; node1.x=begin_x; node1.y=begin_y; node1.time=0; node1.bomb=6; q.push(node1); vis[node1.x][node1.y]=6; //标记时注意走过的点任然可以再走,所以保存的是经过该点的最大爆炸时间 while(!q.empty()) { node2=q.front(); //printf("%d %d %d %d-->\n",node2.x,node2.y,node2.time,node2.bomb); q.pop(); if(node2.x==end_x&&node2.y==end_y) { printf("%d\n",node2.time); return ; } for(int i=0;i<4;i++) { node1.x=node2.x+dx[i]; node1.y=node2.y+dy[i]; if(node1.x>=1&&node1.x<=m&&node1.y>=1&&node1.y<=n) //限制坐标 { if(node2.bomb>=2) //限制前一个点炸弹爆炸的时间 { if(map[node1.x][node1.y]==1||map[node1.x][node1.y]==3) { node1.time=node2.time+1; node1.bomb=node2.bomb-1; if(node1.bomb>vis[node1.x][node1.y]) { q.push(node1); vis[node1.x][node1.y]=node1.bomb; } } if(map[node1.x][node1.y]==4) { node1.time=node2.time+1; node1.bomb=6; if(node1.bomb>vis[node1.x][node1.y]) { q.push(node1); vis[node1.x][node1.y]=node1.bomb; } } } } } } printf("-1\n"); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) { scanf("%d",&map[i][j]); if(map[i][j]==2) { begin_x=i; begin_y=j; } if(map[i][j]==3) { end_x=i; end_y=j; } } bfs(); } return 0; }