题目描述
乔在迷宫中工作。不幸的是,迷宫的一部分着火了,迷宫的主人没有制定火灾的逃跑计划。请帮助乔逃离迷宫。根据乔在迷宫中的位置以及迷宫的哪个方块着火,你必须确定火焰烧到他之前,乔是否可以离开迷宫,如果能离开他能跑多快。
乔和火每分钟移动一个方格,上、下、左、右,四个方向中的一个。火势向四个方向同时蔓延。乔可以从迷宫的任何一个边界逃离迷宫。无论是乔还是火都不会到达有墙的位置。
输入
第一行输入包含一个整数,即测试次数
每个测试用例的第一行包含两个
整数R和C,用空格分隔,1≤R,C≤1000
下面R行中,每一行都包含C个字符,以及每个字符是以下之一:
# 代表墙
. 代表空地,火和乔是可通行的
J 乔在迷宫中最初的位置,火和乔是可通行的
F 代表火
在每组测试中只有一个J
输出
对于每个测试用例,如果在火蔓延的时候烧到了乔,则乔无法逃出迷宫,输出'IMPOSSIBLE'如果乔能逃出迷宫,则输出乔最快可以在几分钟内安全逃出迷宫,每组输出占一行
样例输入
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
样例输出
3
IMPOSSIBLE
思路 : 这个题我写了两个思路,第一个思路是双bfs,第一个bfs遍历全图找到火到每一个点的最短速度 ,判断人走到这里
时的步数,是否小于最短速度,小于便能走;
下面是这个思路的代码
#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
#include<string>
#include<stack>
#define ll long long
using namespace std;
char a[1005][1006];
int book[1005][1005];
int book1[1005][1005];
int vis[1005][1005] ;
int n,m,fx,fy,jx,jy;
const int MAXN = 99999 ;
const int dx[] = {0,0,1,-1};
const int dy[] = {1,-1,0,0};
struct Node
{
int x,y,s;
Node () {}
Node(int xx,int yy,int ss) : x(xx) , y(yy) , s(ss){}
};
int bfs(int x,int y,int s)
{
memset(book1,0,sizeof(book1));
book1[x][y] = 1 ;
queue<Node> Q;
Q.push(Node(x,y,s));
book[x][y] = 0;
while(!Q.empty())
{
Node u = Q.front() ;
Q.pop() ;
for(int i=0 ; i<4 ; i++)
{
int xx = u.x + dx[i] ;
int yy = u.y + dy[i] ;
int ss = u.s + 1 ;
if(xx>=0 && yy>=0 && xx<n && yy<m && a[xx][yy] != '#' && book1[xx][yy] == 0)
{
//cout<<ss<<endl;
//cout<<book[u.x][u.y]<<endl;
book1[xx][yy] = 1 ;
book[xx][yy] = min(book[xx][yy],ss) ;
Q.push(Node(xx,yy,ss)) ;
}
}
}
return -1 ;
}
void bfs1(int x,int y,int s)
{
queue<Node> Q;
Q.push(Node(x,y,s));
vis[x][y] = 1 ;
while(!Q.empty())
{
Node u = Q.front() ;
Q.pop() ;
if(u.x == 0 || u.y == 0 || u.x == n-1 || u.y == m-1)
{
printf("%d\n",u.s+1);
return ;
}
for(int i=0 ; i<4 ; i++)
{
int xx = u.x + dx[i] ;
int yy = u.y + dy[i] ;
int ss = u.s + 1 ;
if(xx>=0 && xx<n && yy>=0 && yy<m && a[xx][yy] != '#' && ss<book[xx][yy] && vis[xx][yy] == 0)
{
vis[xx][yy] = 1 ;
Q.push(Node(xx,yy,ss));
}
}
}
printf("IMPOSSIBLE\n");
return ;
}
int main()
{
int T;
cin>>T;
while(T--)
{
for(int i=0 ; i<1005 ; i++)
{
for(int j=0 ; j<1005 ; j++)
{
book[i][j] = MAXN;
}
}
memset(vis,0,sizeof(vis));
memset(a,0,sizeof(a));
//cout<<book[1][1]<<endl;
cin>>n>>m;
getchar();
for(int i=0 ; i<n ; i++)
{
for(int j=0 ; j<m ; j++)
{
a[i][j] = getchar() ;
if(a[i][j] == 'J')
{
jx = i ;
jy = j ;
}
}
getchar();
}
for(int i=0 ; i<n ; i++)
{
for(int j=0 ; j<m ; j++)
{
if(a[i][j] == 'F')
{
bfs(i,j,0);
}
}
}
/* for(int i=0 ; i<n ; i++)
{
for(int j=0 ; j<m ; j++)
{
cout<<book[i][j]<<" ";
}
cout<<endl;
} */
bfs1(jx,jy,0);
}
return 0;
}
第二个思路一个bfs就能解决问题,所有的火和人都放入队列;
先放火再放人;先走火,火下一步能走的地方,人一定不能走把他变成 ‘#’
#include<iostream>
#include<stdio.h>
#include<queue>
#include<string.h>
#include<algorithm>
#include<string>
#include<stack>
#define ll long long
using namespace std;
char a[1150][1150];
int n,m,fx,fy,jx,jy;
const int inf = 0x3f3f3f3f;
const int dx[] = {1,-1,0,0};
const int dy[] = {0,0,1,-1};
struct Node
{
int x,y,s,f;
Node () {}
Node(int xx,int yy,int ss,int ff) : x(xx) , y(yy) , s(ss) ,f(ff){}
};
queue<Node> Q;
int bfs(int x,int y,int s,int ff)
{
Q.push(Node(x,y,s,ff)) ;
while(!Q.empty())
{
Node u = Q.front() ;
Q.pop() ;
if((u.x == 0 || u.y == 0 || u.x == n-1 || u.y == m-1) && u.f==0)
{
return u.s + 1 ;
}
for(int i=0 ; i<4 ; i++)
{
int xx = u.x + dx[i] ;
int yy = u.y + dy[i] ;
if(xx>=0 && yy>=0 && xx<n && yy<m && a[xx][yy] != '#')
{
int ss = u.s + 1 ;
int ff = u.f ;
a[xx][yy] = '#' ;
Q.push(Node(xx,yy,ss,ff)) ;
}
}
}
return -1 ;
}
int main()
{
int T;
cin>>T;
while(T--)
{
while(!Q.empty())
{
Q.pop() ;
}
// memset(book,inf,sizeof(book));
scanf("%d%d",&n,&m);
// getchar();
for(int i=0 ; i<n ; i++)
{
for(int j=0 ; j<m ; j++)
{
cin>>a[i][j] ;
}
// getchar();
}
for(int i=0 ; i<n ; i++)
{
for(int j=0 ; j<m ; j++)
{
if(a[i][j] == 'F')
{
Q.push(Node(i,j,0,1));
}
if(a[i][j] == 'J')
{
jx=i;
jy=j;
}
}
}
int ans = bfs(jx,jy,0,0);
if(ans==-1)
{
cout<<"IMPOSSIBLE"<<endl;
}
else
{
cout<<ans<<endl;
}
}
return 0;
}
多谢各位学长的思路,和帮忙debug ;