UVA 11624 Fire!

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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值