题目:
\
\
思路:
给了很多个火(F)和一个人(J),火和人想四面蔓延的速度都是1,问人能否走出迷宫,思路是先给地图外围加一圈点来判断是否走出迷宫,然后把人的位置和火焰的位置都记录下来,先让火焰入队,最后让人入队,用两个标记数组来标记火和人是否有走过或者烧过,因为火可以烧人走过的,
'#'代表墙
'.'代表路
'F'代表火
'J'代表人
代码:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
char map[1005][1005];
int vis[1005][1005];//火烧
int vix[1005][1005];//人走
int go[4][2]= {{0,1},{0,-1},{-1,0},{1,0}};//四个方向
int m,n,num,x1,y1;
struct node
{
int x,y,s,id;//人的id为0,火的id为1
} a[1000];
int bfs(int num)
{
node now,to;
queue<node>q;
for(int i=0; i<num; i++)
{
q.push(a[i]);
vis[a[i].x][a[i].y]=1;//先把火焰入队,并且标记烧过的
}
q.push(a[num]);
vix[a[num].x][a[num].y]=1;//把人入队,标记走过的
while(!q.empty())
{
now=q.front();
if(now.id==0&&(now.x<1||now.y<1||now.x>n||now.y>m))return now.s;//当走出迷宫时返回步数
for(int i=0; i<4; i++)
{
to.x=now.x+go[i][0];
to.y=now.y+go[i][1];
to.s=now.s+1;
to.id=now.id;
if(to.id==0&&vix[to.x][to.y]==0&&vis[to.x][to.y]==0&&map[to.x][to.y]=='.')//如果是人,当且仅当火没烧过,人没走过时,可以继续搜下去
{
vix[to.x][to.y]=1;//人走过标记为1
q.push(to);
}
if(to.id==1&&vis[to.x][to.y]==0&&to.x>0&&to.x<=n&&to.y>0&&to.y<=m&&map[to.x][to.y]=='.')//判断是否越界,及能不能继续烧
{
vis[to.x][to.y]=1;//火烧过的标记
q.push(to);
}
}
q.pop();
}
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
mem(map,0);
mem(vis,0);
mem(vix,0);//初始化
num=0;
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)
{
scanf("%s",map[i]+1);
for(int j=1; j<=m; j++)
{
if(map[i][j]=='F')//找到火焰
{
a[num].x=i;
a[num].y=j;
a[num].id=1;
a[num].s=0;
num++;
}
if(map[i][j]=='J')//找到人
{
x1=i;
y1=j;
}
}
}
a[num].x=x1;
a[num].y=y1;
a[num].s=0;
a[num].id=0;
for(int i=0; i<=n+1;i++)//外边围一圈点
{
map[i][0]='.';
map[i][m+1]='.';
}
for(int i=0; i<=m+1; i++)
{
map[0][i]='.';
map[n+1][i]='.';
}
int ans=bfs(num);
if(ans)
printf("%d\n",ans);
else
printf("IMPOSSIBLE\n");
}
return 0;
}
\