CF1463-C. Busy Robot
发布日期:2021-05-13 02:07:35 浏览次数:18 分类:博客文章

本文共 2071 字,大约阅读时间需要 6 分钟。

题意:

你有一个机器人,这个机器人在一维坐标轴上移动。你可以给这个机器人下达指令,指令的形式为 \(t_i, x_i\) ,意味着机器人在第\(t_i\)秒的时候获得一条指令,此时这个机器人以\(1/s\)的速度从现在的位置开始向\(x_i\)移动。若机器人执行当前指令的过程中收到其他命令,那么其他命令会被忽略。

现在问你给出的指令中被成功执行的命令有几条,被成功执行的命令的定义并不是字面意义上的成功之行,题目给出的成功之行命令的条件为:

假设当前命令为 \(t_i, x_i\) , 若机器人在 \(t_i\)\(t_{i+1}\)这个时间区间(包括边界)内到达过 \(x_i\) 这个位置,则称这条命令被成功执行。

对于最后一条命令 \(t_n, x_n\) ,我们认为有一个\(t_{n+1}=∞\)

思路:

从第一条命令开始,我们记录它的起始时间 \(start\_time\) ,结束时间 \(end\_time\) ,之后排着扫命令:

  • 若命令的\(t_i\) 小于\(start\_end\) , 那么就算出 \(t_i\) 时机器人的位置和 \(min(t_{i+1}, end\_time)\) 时机器人的位置,若 \(x_i\) 在这个区间内,那么这条命令就算被成功执行了;

  • 若命令的 \(t_i\) 大于等于 \(start\_time\) , 那么就更新\(start\_time\)\(end_time\)

本题有一些处理上的小技巧,可以在代码中看到。

此外这道题个地方需要注意:题目里说的认为有一个 \(t_{n+1}=∞\) , 这里我最开始的代码无穷取了 \(0x3F3F3F3F\) , 但是这里无穷取这个值会出问题,因为他的范围是从 \(-10^9 <= x_i <= 10^9\), 若数据给了从最左边到最右边是最后一个指令,那么取这个值会导致它不能走到最右边。(这个地方卡了我一下午。。)

AC代码:

#include 
#include
typedef long long ll;const int maxn = 1e5 + 5;const ll inf = 0x3f3f3f3f3f3f3f3f;struct node { ll t, p;}a[maxn];int main () { int T, n; scanf ("%d", &T); while (T--) { scanf ("%d", &n); for (int i = 0; i < n; i++) { scanf ("%lld %lld", &a[i].t, &a[i].p); } a[n].t = inf; ll start_pos = 0; ll end_pos = 0; ll start_time = 0; ll end_time = -1; ll dir = 0; int ans = 0; for (int i = 0; i < n; i++) { if (a[i].t >= end_time) { start_pos = end_pos; end_pos = a[i].p; start_time = a[i].t; end_time = start_time + std::abs(a[i].p - start_pos); dir = (a[i].p - start_pos) == 0 ? 0 : (a[i].p - start_pos) / std::abs(a[i].p - start_pos); } ll s = start_pos + (a[i].t - start_time) * dir; ll t = start_pos + (a[i + 1].t - start_time) * dir; if (a[i + 1].t > end_time) { t = end_pos; } if (s > t) std::swap (s, t); if (a[i].p >= s && a[i].p <= t) { ans++; } } printf ("%d\n", ans); } return 0;}
上一篇:CF1463-D. Pairs
下一篇:CF1463-B. Find The Array

发表评论

最新留言

哈哈,博客排版真的漂亮呢~
[***.90.31.176]2025年04月27日 15时29分20秒