AtCoder Beginner Contest 241(Sponsored by Panasonic)

from AtCoder Beginner Contest 241(Sponsored by Panasonic)

F.Skate

题意

H x W 的网格,存在 n 个障碍,已知起点和终点,询问从起点走到终点需要几步。

网格大小为 1e9x1e9,存在1e5 个障碍。

移动规则如下:

从当前位置,选择上下左右的某一个方向移动,遇到障碍时才能在障碍的前一格停止。

特别的是,边界不属于障碍,即若某一方向上无障碍,无法向该方向移动。

题解

首先,我们发现,需要标记和移动的点只有障碍周围的点,因此,这道题就相当于是4n * 4n 的网格上的BFS。

这道题的点主要是在于如何找到下一步移动到达的位置。

我们可以用一个map套set(也不是非得这么存),分别存下每一行和每一列上的障碍位置,在查询下一步的时候,在当前行或列二分出下一个位置即可。

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int H, W, n, sx, sy, gx, gy;
map<int, set<int>>r,c;
map<pair<int, int>, bool>vis;
struct node { int x, y, s; };
int dx[10] = { 0,0,1,-1 }, dy[10] = { 1,-1,0,0 }, df[5] = { -1,0,1 };

bool ok(int x, int y) {
	if (x >= 1 && x <= H && y >= 1 && y <= W)return 1;
	return 0;
}

int main() {
	cin >> H >> W >> n;
	cin >> sx >> sy >> gx >> gy;
	for (int i = 0; i < n; i++) {
		int x, y;
		cin >> x >> y;
		r[x].insert(y), c[y].insert(x);
    }
	queue<node>que;
	que.push({ sx, sy, 0 });
	vis[{sx, sy}] = 1;
	while (!que.empty()) {
		node p = que.front(); que.pop();

		if (p.x == gx && p.y == gy) {
			cout << p.s << "\n";
			return 0;
		}

		auto fx = r[p.x].lower_bound(p.y), fy = c[p.y].lower_bound(p.x);
		
		if (fx != r[p.x].end() && !vis[{p.x, * fx - 1}])que.push({ p.x,*fx - 1,p.s + 1 }), vis[{ p.x, * fx - 1}] = 1;
		if (fy != c[p.y].end() && !vis[{*fy - 1, p.y}])que.push({ *fy - 1, p.y,p.s + 1 }), vis[{*fy - 1, p.y}] = 1;
		if (fx != r[p.x].begin()) {
			fx--;
			if (!vis[{p.x, * fx + 1}])que.push({ p.x,*fx + 1,p.s + 1 }), vis[{p.x, * fx + 1}] = 1;
		}
		if (fy != c[p.y].begin()) {
			fy--;
			if (!vis[{*fy + 1, p.y}])que.push({ *fy + 1, p.y,p.s + 1 }), vis[{*fy + 1, p.y}] = 1;
		}
	}
	cout << "-1\n";
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值