HDU 3085 双向BFS

本文介绍了一种使用双方向广度优先搜索算法解决特定迷宫问题的方法,具体为判断男女角色能否在限定条件下相遇。文章通过C++实现,考虑了不同角色的移动速度和特殊障碍(如僵尸)的存在。

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

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn = 1e3 + 10;
#define Dis(a,b) abs((a).x-(b).x)+abs((a).y-(b).y)
int dir[4][2] = {{ -1, 0}, {1, 0}, {0, -1}, {0, 1}};
bool vis[maxn][maxn][2];
char inp[maxn][maxn];
int n, m, T, cnt;
struct Node
{
	int x, y;
	Node(int x = 0, int y = 0): x(x), y(y) {}
	Node move(int i)
	{
		return Node(x + dir[i][0], y + dir[i][1]);
	}
	bool Judge();
};
queue<Node>Q[2];
Node M, G, Z[2];
bool Node::Judge()
{
	if (x >= 0 && x < n && y >= 0 && y < m && inp[x][y] != 'X')
	{
		if (Dis(*this, Z[0]) <= 2 * cnt || Dis(*this, Z[1]) <= 2 * cnt)
			return false;
		else return true;
	}
	else return false;
}
int BFS(int num)
{
	int k = Q[num].size();
	while (k--)
	{
		Node pos = Q[num].front(); Q[num].pop();
		if (pos.Judge())
			for (int i = 0; i < 4; i++)
			{
				Node tmp = pos.move(i);
				if (tmp.Judge() && !vis[tmp.x][tmp.y][num])
				{
					if (vis[tmp.x][tmp.y][!num]) return true;
					else vis[tmp.x][tmp.y][num] = true, Q[num].push(tmp);
				}
			}
	}
	return false;
}
int Dual_BFS()
{
	memset(vis, 0, sizeof(vis));
	while (!Q[0].empty()) Q[0].pop();
	while (!Q[1].empty()) Q[1].pop();
	Q[0].push(M); Q[1].push(G);
	vis[M.x][M.y][0] = vis[G.x][G.y][1] = true;
	cnt = 0;
	while (!Q[0].empty() || !Q[1].empty())
	{
		cnt++;
		if (BFS(0) || BFS(0) || BFS(0) || BFS(1))
			return cnt;
	}
	return -1;
}
int main(int argc, char const *argv[])
{
	scanf("%d", &T);
	while (T--)
	{
		cnt = 0;
		scanf("%d%d", &n, &m);
		for (int i = 0; i < n; i++)
		{
			scanf("%s", inp[i]);
			for (int j = 0; j < m; j++)
			{
				if (inp[i][j] == 'M') M = Node(i, j);
				else if (inp[i][j] == 'G') G = Node(i, j);
				else if (inp[i][j] == 'Z') Z[cnt++] = Node(i, j);
			}
		}
		printf("%d\n", Dual_BFS());
	}
	return 0;
}




男人一次走三格,女人一下走一格,不能翻墙,鬼一下走两格,可以翻墙。问男女能否相遇。

是否会被鬼抓住,直接用两点之间的曼哈顿距离判定就可以了。双向广搜避免超时。


男人一次走三格,女人一下走一格,不能翻墙,鬼一下走两格,可以翻墙。问男女能否相遇。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值