JZOJ·神殿【BFS】

本文介绍了解决JZOJ2296神殿迷宫问题的方法,通过宽度优先搜索(BFS)算法,在O(nm4)的时间复杂度下寻找从起点到终点的最短路径。文章详细展示了读取地图信息、进行状态转移和边界检查的过程,并提供了完整的C++代码实现。

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

Description–

在这里插入图片描述


Input–

在这里插入图片描述

Output–

在这里插入图片描述


Sample Input–

样例输入1

2 2
+*
*U
1 1 2 2

样例输入2

2 3
<><
><>
1 1 2 1

Sample Output–

样例输出1

-1

样例输出2

4

说明–

在这里插入图片描述题目标中的特殊符号:<>^v+*|-


解题思路–

BFS就可以了,时间复杂度O(nm4)


代码–

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
int fx[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int n,m,x,y,xx,yy;
bool f[1005][1005][4],pd[1005][1005][4];
struct ooo
{
	int xr,yr,time,turn;
};
void read()
{
	char c;
	for (int i=1;i<=n;++i)
	{
		c=getchar();
		for (int j=1;j<=m;++j)
		{
			c=getchar();
			if (c=='^' || c=='|' || c=='L' || c=='R' || c=='D' || c=='+') f[i][j][0]=1;
			if (c=='<' || c=='-' || c=='U' || c=='R' || c=='D' || c=='+') f[i][j][1]=1;
			if (c=='v' || c=='|' || c=='L' || c=='R' || c=='U' || c=='+') f[i][j][2]=1;
			if (c=='>' || c=='-' || c=='L' || c=='U' || c=='D' || c=='+') f[i][j][3]=1;
		}
	}
}
void bfs()
{
	queue<ooo> l;
	ooo fff;
	fff.xr=x,fff.yr=y,fff.time=0,fff.turn=0;
	pd[x][y][0]=1;
	l.push(fff);
	while (!l.empty())
	{
		fff=l.front();
		l.pop();
		if (!pd[fff.xr][fff.yr][(fff.turn+1)%4])
		{
			ooo ff;
			ff.xr=fff.xr,ff.yr=fff.yr,ff.time=fff.time+1,ff.turn=(fff.turn+1)%4;
			l.push(ff);
			pd[ff.xr][ff.yr][ff.turn]=1;
		}
		for (int i=0;i<4;++i)
		{
			int xe=fff.xr+fx[i][0];
			int ye=fff.yr+fx[i][1];
			if (xe>0 && ye>0 && xe<=n && ye<=m)//越界
		      if (!pd[xe][ye][fff.turn])
		        if (f[fff.xr][fff.yr][(fff.turn+i)%4])//有路
		          if (f[xe][ye][(fff.turn+i+2)%4])    //可走
		          {
		          	  ooo ff;
		          	  ff.xr=xe,ff.yr=ye,ff.time=fff.time+1,ff.turn=fff.turn;
		          	  if (ff.xr==xx && ff.yr==yy)//到辽
		          	  {
		          	  	  printf("%d",ff.time);
		          	  	  return ;
		          	  }
					  l.push(ff);
					  pd[ff.xr][ff.yr][ff.turn]=1;
		          }
		}
	}
	printf("-1");//到不了
}
int main()
{
	freopen("temple.in","r",stdin);
	freopen("temple.out","w",stdout);
	
    scanf("%d%d",&n,&m);
	read();
	scanf("%d%d%d%d",&x,&y,&xx,&yy);
	if (x==xx && y==yy)
	{
		printf("0");
		return 0;
	}
	bfs();
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值