题意:就是问你能不能在火烧到你之前,走出一个矩形区域,如果有,求出最短的时间
分析:两遍BFS,然后比较边界

#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cmath> #include<map> #include<queue> #include<stdlib.h> #include<string> #include<set> using namespace std; typedef long long LL; const int maxn=1005; const int INF=0x3f3f3f3f; char s[maxn][maxn]; int mp[maxn][maxn]; int v[maxn][maxn]; int n,m; struct Point { int x,y; Point() {} Point(int a,int b) { x=a,y=b; } } o,t; queue<Point>q,e; int dx[4]= {0,0,-1,1}; int dy[4]= {-1,1,0,0}; int main() { int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=1; i<=n; ++i) scanf("%s",s[i]+1); for(int i=1; i<=n; ++i) { for(int j=1; j<=m; ++j) { mp[i][j]=v[i][j]=-1; if(s[i][j]=='F')q.push(Point(i,j)),mp[i][j]=0; else if(s[i][j]=='J')e.push(Point(i,j)),v[i][j]=0; } } while(!q.empty()) { o=q.front(); q.pop(); for(int i=0; i<4; ++i) { t.x=o.x+dx[i]; t.y=o.y+dy[i]; if(t.x<1||t.x>n||t.y<1||t.y>m)continue; if(s[t.x][t.y]=='#'||mp[t.x][t.y]!=-1)continue; mp[t.x][t.y]=mp[o.x][o.y]+1; q.push(t); } } while(!e.empty()) { o=e.front(); e.pop(); for(int i=0; i<4; ++i) { t.x=o.x+dx[i]; t.y=o.y+dy[i]; if(t.x<1||t.x>n||t.y<1||t.y>m)continue; if(s[t.x][t.y]=='#'||v[t.x][t.y]!=-1)continue; v[t.x][t.y]=v[o.x][o.y]+1; e.push(t); } } int ans=INF; for(int i=1;i<=n;++i) { if(v[i][1]!=-1) { if(mp[i][1]==-1||v[i][1]<mp[i][1]) ans=min(ans,v[i][1]); } if(v[i][m]!=-1) { if(mp[i][m]==-1||v[i][m]<mp[i][m]) ans=min(ans,v[i][m]); } } for(int i=1;i<=m;++i) { if(v[1][i]!=-1) { if(mp[1][i]==-1||v[1][i]<mp[1][i]) ans=min(ans,v[1][i]); } if(v[n][i]!=-1) { if(mp[n][i]==-1||v[n][i]<mp[n][i]) ans=min(ans,v[n][i]); } } if(ans==INF)printf("IMPOSSIBLE "); else printf("%d ",ans+1); } return 0; }