UVA的题没法愉快的复制粘贴,所以直接上链接吧(汗。
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671
这个题一开始没好好看,结果迷之TLE两次。搞了半天原来是我没看到起火点可能不止一处…………
看到有大牛的代码就开了一个队列,把火和人放一块,一次bfs搞定,不过我太弱了做不到OTZ
我写的方法就是先把火会到的地点的时间记录一下,然后再让人走,人走的步数和火会烧到的时间做一下对比,如果步数大于等于时间的话,这一块就不能走。
总的来说还是bfs了两次。
题意:J被困在了一个地方,这个地方有一些墙#和火源F,火源F每一刻都会向上下左右扩散,扩散的地方就不能走了。只要走到边界处,J就能离开这里。问:J能离开吗?能的话最少需要多长时间?
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#define INF 0x3f3f3f3f
using namespace std;
int R,C,x1,y1,k;
int dis[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int num1[1010][1010],num2[1010][1010];
char map[1010][1010];
struct node
{
int x,y;
}a[1010*1010];
int OK(node a)
{
if(a.x>=0&&a.y>=0&&a.x<R&&a.y<C&&map[a.x][a.y]!='#')
return 1;
return 0;
}
void bfs_fire()
{
int i;
queue<node> q;
for(i=0;i<k;i++)
{
q.push(a[i]);
num1[a[i].x][a[i].y]=1;
}
while(!q.empty())
{
node now,next;
now=q.front();
q.pop();
for(i=0;i<4;i++)
{
next.x=now.x+dis[i][0];
next.y=now.y+dis[i][1];
if(OK(next)&&num1[next.x][next.y]==INF)
{
num1[next.x][next.y]=num1[now.x][now.y]+1;
q.push(next);
}
}
}
}
int bfs()
{
int i;
node now,next;;
queue<node> q;
now.x=x1,now.y=y1;
num2[now.x][now.y]=1;
q.push(now);
while(!q.empty())
{
now=q.front();
q.pop();
if(now.x==0||now.y==0||now.x==R-1||now.y==C-1)
if(num2[now.x][now.y]<num1[now.x][now.y])
return num2[now.x][now.y];
for(i=0;i<4;i++)
{
next.x=now.x+dis[i][0];
next.y=now.y+dis[i][1];
if(OK(next)&&num2[next.x][next.y]==0)
{
num2[next.x][next.y]=num2[now.x][now.y]+1;
q.push(next);
}
}
}
return -1;
}
int main()
{
int T;
int i,j;
scanf("%d",&T);
while(T--)
{
k=0;
scanf("%d%d",&R,&C);
for(i=0;i<R;i++)
{
scanf("%s",map[i]);
for(j=0;j<C;j++)
{
num1[i][j]=INF;
if(map[i][j]=='J')
x1=i,y1=j;
if(map[i][j]=='F')
{
a[k].x=i;a[k].y=j;
k++;
}
}
}
bfs_fire();
memset(num2,0,sizeof(num2));
int ans=bfs();
if(ans==-1)
printf("IMPOSSIBLE\n");
else
printf("%d\n",ans);
}
return 0;
}