蓝桥杯 算法提高 拯救Andy BFS C++

这篇博客介绍了一种使用广度优先搜索(BFS)算法来求解地图上从任意位置到最近绿洲的最短路径问题。通过建立一个二维数组存储每个位置到绿洲的最短距离,并用队列进行节点的遍历,不断更新相邻位置的距离。算法会避免毒蛇区域并确保所有可达的绿洲都被考虑。最终,计算整个地图上所有位置到绿洲的最短路径总和。
摘要由CSDN通过智能技术生成

思路:
首先将所有的绿洲加入队列中,每次从队列中取一个元素,查询周围的8个坐标(需要注意边界条件)的最小距离是否可以被更新,如果相邻坐标被更新则将该坐标加入队列中。
代码:

#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define MAX 100000000
struct Pos
{
	int x, y;
};
void bfs(queue<Pos>& q, vector<vector<int> >& f);

// 可以走的周围的八个格子,可以自己画一下
int d[8][2] = { {-1,-1},{0,-1},{1,-1},
				{-1,0},{1,0},
				{-1,1},{0,1},{1,1}
			   };
int n, m, p;
int main()
{
	cin >> n >> m >> p;
	vector<vector<int> > f(n + 1, vector<int>(n + 1, MAX));	//  地图,存储从一个坐标到绿洲的最短距离
	for (int i = 0; i < m; i++)
	{
		int x, y;
		cin >> x >> y;
		f[x][y] = -1;	// 毒蛇
	}
	queue<Pos> q;
	for (int i = 0; i < p; i++)
	{
		int x, y;
		cin >> x >> y;
		Pos tmp;
		tmp.x = x;
		tmp.y = y;
		q.push(tmp);	// 把绿洲加入到队列中,绿洲到本身距离为0
		f[x][y] = 0;
	}
	bfs(q, f);
	long long res = 0;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			if (f[i][j] == MAX) f[i][j] = -1;	// 如果这个坐标没有被更新,表明从这个点到不了任何一个绿洲
			res += f[i][j];
		}
	}
	cout << res << endl;
	return 0;
}
void bfs(queue<Pos>& q, vector<vector<int> >& f)
{
	while (!q.empty())
	{
		Pos tmp = q.front();
		q.pop();
		for (int i = 0; i < 8; i++)	 // 遍历八个方向
		{
			int x = tmp.x + d[i][0];
			int y = tmp.y + d[i][1];
			if (x <= n && x >= 1 && y <= n && y >= 1 && f[x][y] > 0)	 // 处理越界,该坐标是绿洲或毒蛇时不更新
			{
				if (f[tmp.x][tmp.y] + 1 < f[x][y])	// 如果被更新,将该坐标加入到队列中,因为与之相邻的坐标到绿洲的最小距离可能由从该点走而变短
				{
					f[x][y] = f[tmp.x][tmp.y] + 1;
					Pos pos;
					pos.x = x;
					pos.y = y;
					q.push(pos);
				}
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值