IMPOSSIBLE
点击打开链接
//分析 看到这题目以为很好搞 好久没写 不熟练 搞了一个晚上
首先用BFS人走 book记录有没走过 题目说火不能过墙 所以要用Book记录而不能用map=# 坑 其次总体思路就是扩散 但不同于一般就是要搞一个循环将每一次进队的一个时间点所有都枚举 在代码中num循环那里 之前只记得将火每次扩散 忘了将人走的也要扩散 导致wa 意思是
c
c b c
c b a b c
c b c
c
一个字母类型代表1分钟 每一个时刻要将四个方向以前进队的拿出来扩散新的进队 而不是像简单的BFS每次出一点枚举 这里是要每次4个点
第一次源点1个 第二次源点周围4个 abcd 第三次就要枚举abcd各自的四个方向
//AC代码
#include <iostream> #include <cstdio> #include <queue> #include <string.h> using namespace std; const int N=1000+10; char map[N][N]; struct Node{ int x,y,step; }; bool book[N][N]; queue<Node> q,fire; int next[4][2]={{0,1},{1,0},{-1,0},{0,-1}}; int n,m; /*inline void print(){ for(int i=0;i<n;i++){ for(int j=0;j<m;j++) printf("%c ",map[i][j]); printf("\n"); } }*/ int main(){ bool ok; Node node,tmp; int t,i,j,fx,fy; char c[N]; scanf("%d",&t); while(t--){ ok=0; memset(book,0,sizeof(book)); scanf("%d%d",&n,&m); for(i=0;i<n;i++){ scanf("%s",c); for(j=0;j<m;j++){ map[i][j]=c[j]; if(c[j]=='F'){ node.x=i; node.y=j; fire.push(node); } else if(c[j]=='J'){ //用book设置人是不是走过了 不要用#代替 不然火不能烧人 book[i][j]=1; node.x=i; node.y=j; node.step=0; q.push(node); } } } while(!q.empty()){ int num=q.size(); for(j=0;j<num;j++){ node=q.front(); q.pop(); if(map[node.x][node.y]=='F') //这个点不行了 被火烧了 continue; for(i=0;i<4;i++){ int a=node.x+next[i][0]; int b=node.y+next[i][1]; if(a<0||a>=n||b<0||b>=m) { ok=1; break; } //墙和火不能走 忘了+火 超时了 //用book设置人是不是走过了 不要用#代替 不然火不能烧人 if(map[a][b]=='#'||map[a][b]=='F'||book[a][b]==1) continue; book[a][b]=1; tmp.x=a; tmp.y=b; tmp.step=node.step+1; q.push(tmp); } } if(ok) break; num=fire.size(); for(j=0;j<num;j++){ node=fire.front(); fire.pop(); for(i=0;i<4;i++){ int a=node.x+next[i][0]; int b=node.y+next[i][1]; //题目要求障碍物 墙 不能被烧 郁闷 害我wa if(a<0||a>=n||b<0||b>=m||map[a][b]=='#'||map[a][b]=='F') continue; map[a][b]='F'; tmp.x=a; tmp.y=b; fire.push(tmp); } } // print(); } if(ok) printf("%d\n",node.step+1); else printf("IMPOSSIBLE\n"); while(!q.empty()) q.pop(); while(!fire.empty()) fire.pop(); } return 0; }