CF877D Olya and Energy Drinks 题解

这道题是蓝题好像多余了。

一看到最短时间,我们第一反应就是 BFS,但是这道题仅仅 BFS 不够,要加一些剪枝优化,例如对下面这个例子:

4 4 10
..#.
...#
..##
.###
1 1 3 2

第一,我们从坐标 (1,1) 出发,这时我们可以向右 1~10 步,但是我们发现当我们走 2 步时已经有一个 # 了,这时我们可以直接跳出循环,因为后面已经不可能了。

第二,从坐标 (1,1) 出发,我们可以向下 10 格,但是走了 4 格就已经越界了,那我们也不用走了,为什么呢?因为,若 a+b>na+b>n,且有一数 cc 满足 c>bc>b,则 a+c>na+c>n废话)。

稍微注意一下这几点就好了,至于状态压缩我是没用,也过了:

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;

int n, m, p;
const int N = 1e3 + 5;
char ch[N][N];
int start_x, start_y, end_x, end_y;
bool visit[N][N];

int dx[4] = { 0, 0, 1, -1 };
int dy[4] = { 1, -1, 0, 0 };

struct Node
{
	int x, y, times;
};

void bfs()
{
	queue<Node> q;
	Node l;
	l.x = start_x;
	l.y = start_y;
	l.times = 0;
	q.push(l);
	visit[start_x][start_y] = true;
	while (!q.empty())
	{
		Node k = q.front(), s;
		q.pop();
		s.times = k.times + 1;
		for (int i = 0; i < 4; i++)
		{
			for (int j = 1; j <= p; j++)
			{
				s.x = k.x + dx[i] * j;
				s.y = k.y + dy[i] * j;
				if (s.x <= 0 || s.x > n || s.y <= 0 || s.y > m || ch[s.x][s.y] == '#') break;
				if (visit[s.x][s.y]) continue;
				visit[s.x][s.y] = true;
				q.push(s);
				if (s.x == end_x && s.y == end_y)
				{
					cout << s.times << endl;
					return;
				}
			}
		}
	}
	cout << "-1\n";
}

int main()
{
	cin >> n >> m >> p;
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= m; j++) cin >> ch[i][j];
	}
	cin >> start_x >> start_y >> end_x >> end_y;
	if (start_x == end_x && start_y == end_y)
	{
		cout << "0\n";
		return 0;
	}
	bfs();
	return 0;
}
posted @   HappyBobb  阅读(24)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示