FZU escape(两个bfs)

本文介绍了一种解决特殊迷宫逃脱问题的方法,利用两次广度优先搜索(BFS)算法来模拟岩浆蔓延及玩家逃脱过程。首次BFS用于预处理岩浆到达各格子的时间,第二次BFS则模拟玩家的移动路径,确保玩家总能在岩浆前一步到达出口。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:点击打开

终于把它给过了,wa了好多好多次,一个页面基本上都是我提交的wa大哭就因为没有判断准确符号问题,这道题是

按着网上的答案来写的,思路:这道题不是简单的bfs问题,因为每个格子时刻在变化着,它可以走也可以不走,所以

呢,我们需要先把每个格子可以走的时间算出来,算出他们被岩浆覆盖时的时间,然后就可以判断能不能走该格子了,

先用一个bfs来与处理一下岩浆蔓延到每个格子的时间,再用一个bfs来模拟游戏的路线,注意:题上已经说明了,如果

走到了E就算成功逃出,所以如果岩浆和小孩同时到达了E就算成功逃出,其他的格子不能他们同时出现(我就是在这个

地方wa的。。。。但是我不明白为什么用GNU c++交会出现编译错误。。)贴代码:

#include <cstdio>  
#include <cstring>  
#include<queue>
using namespace std;
typedef struct
{
	int i,j,step;
}node;
int  time[1005][1005];//用来表示岩浆到达格子所用的最少时间
int visit[1005][1005];//标记是否已经访问过该点
char a[1005][1005];
int dx[4]={-1,0,0,1};
int dy[4]={0,-1,1,0};
int si,sj,ei,ej;
int n,m;
int const INF = 0x7fffffff; 
int ok(int x,int y)
{
	if(x>=1&&y>=1&&x<=n&&y<=m)
		return 1;
	return 0;
}
void bfs1()//预处理每个格子什么时候可以走
{
	int i,j;
	queue <node> q;//建立一个队列,将岩浆发源地入队
	for(i=1;i<=n;i++)
	{
		for(j=1;j<=m;j++)
		{
			if(a[i][j]=='!')
			{
				node p;
				time[i][j]=0;
				p.i=i;
				p.j=j;
				p.step=0;
				q.push(p);
			}
		}
	}
	while(!q.empty())
	{
		node t,w;
		w=q.front();
		q.pop();
		for(i=0;i<4;i++)
		{
			 t.i=w.i+dx[i];
			 t.j=w.j+dy[i];
			 t.step=w.step+1;
			if(ok(t.i,t.j)&&time[t.i][t.j]>t.step)
				{
				  time[t.i][t.j]=t.step;
				  q.push(t);
				}
		}
	}
	return;
}
int bfs2(int x,int y)
{
	queue <node> qq ;
	node w;
	w.i=x;
	w.j=y;
	w.step=0;
	qq.push(w);
	visit[w.i][w.j]=1;
	while(!qq.empty())
	{
		node t,p;
		t=qq.front();
		qq.pop();
		if(t.i==ei&&t.j==ej&&p.step<=time[ei][ej])
			{
			printf("Yes\n");
			 return 0;}
		for(int i=0;i<4;i++)
		{
		    p.i=t.i+dx[i];
		    p.j=t.j+dy[i];
		    p.step=t.step+1;
		    if(p.i==ei&&p.j==ej&&p.step<=time[ei][ej])
				{
					printf("Yes\n");
			 return 0;}
		    if(ok(p.i,p.j)&&!visit[p.i][p.j]&&p.step<time[p.i][p.j])
		    {
		    	visit[p.i][p.j]=1;
		    	qq.push(p);
		    }
		}
	}
	printf("No\n");
	return 0;
}
int main()
{
	int t,i,j;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		if(n==0||m==0) 
		{
			printf("No\n");
			continue;
		}
		memset(visit,0,sizeof(visit));
		for(i=1;i<=n;i++)
		{
			scanf("%s",a[i]+1);
			for(j=1;j<=m;j++)
			{
				time[i][j]=INF;//将每个格子的初值都设为最大
				if(a[i][j]=='S')
				{
					si=i;
					sj=j;
				}
				if(a[i][j]=='E')
				{
					ei=i;
					ej=j;
				}
				if(a[i][j]=='#')
					time[i][j]=0;//墙的时间为0,证明是不可以走的,也可以设为已访问过
			}
		}
		bfs1();
		bfs2(si,sj);
	}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值