#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
int n,m;
#define N 1002
#define inf 0x7f7f7f7f
char maze[N][N];
int m_f[N][N];
bool vis[N][N];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
struct node{
int x,y,steps;
}jp;
bool judge(node st){
if(st.x<0||st.y<0||st.x>=n||st.y>=m) return false;
return true;
}
queue<node> q;
void min_steps(){
while(!q.empty()){
node a=q.front();
q.pop();
m_f[a.x][a.y]=a.steps;
for(int i=0;i<4;i++){
node b;
b.x=a.x+dx[i];
b.y=a.y+dy[i];
if(!judge(b)) continue;
if(maze[b.x][b.y]=='#'||vis[b.x][b.y]==1) continue;
vis[b.x][b.y]=1;
b.steps=a.steps+1;
q.push(b);
}
}
}
int bfs(){
queue<node> p;
memset(vis,0,sizeof(vis));
p.push(jp);
while(!p.empty()){
node a=p.front();
p.pop();
if(a.x==0||a.x==n-1||a.y==0||a.y==m-1) return a.steps+1;
for(int i=0;i<4;i++){
node b;
b.x=a.x+dx[i];
b.y=a.y+dy[i];
if(!judge(b)) continue;
if(m_f[b.x][b.y]<=a.steps+1||maze[b.x][b.y]=='#'||vis[b.x][b.y]==1) continue;
vis[b.x][b.y]=1;
b.steps=a.steps+1;
p.push(b);
}
}
return -1;
}
int main(){
int t;
scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
fill(m_f[i],m_f[i]+m,inf);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
cin>>maze[i][j];
}
while(!q.empty()) q.pop();
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(maze[i][j]=='J'){
jp.x=i;
jp.y=j;
jp.steps=0;
}
if(maze[i][j]=='F'){
// min_steps(i,j);
m_f[i][j]=0;
node temp;
temp.x=i;
temp.y=j;
temp.steps=0;
vis[i][j]=1;
q.push(temp);
}
}
}
/* for(int i=0;i<n;i++){
for(int j=0;j<m;j++)
printf("%-10d ",m_f[i][j]);
puts("");
}*/
min_steps();
int result=bfs();
if(result==-1) printf("IMPOSSIBLE\n");
else printf("%d\n",result);
}
return 0;
}
这道题意思很简单,两次bfs,自己在做的时候主要问题是超时,这主要是自己处理问题的方式还不纯熟。
刚开始我是对每一个F点bfs一次。。。比较大小。。。其实帮F全部放入队列一次就行了。。。