CF1463-C. Busy Robot

CF1463-C. Busy Robot

题意:

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

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

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

对于最后一条命令 t n , x n t_n, x_n tn,xn ,我们认为有一个 t n + 1 = ∞ t_{n+1}=∞ tn+1=

思路:

从第一条命令开始,我们记录它的起始时间 s t a r t _ t i m e start\_time start_time ,结束时间 e n d _ t i m e end\_time end_time ,之后排着扫命令:

  • 若命令的 t i t_i ti 小于 s t a r t _ e n d start\_end start_end , 那么就算出 t i t_i ti 时机器人的位置和 m i n ( t i + 1 , e n d _ t i m e ) min(t_{i+1}, end\_time) min(ti+1,end_time) 时机器人的位置,若 x i x_i xi 在这个区间内,那么这条命令就算被成功执行了;
  • 若命令的 t i t_i ti 大于等于 s t a r t _ t i m e start\_time start_time , 那么就更新 s t a r t _ t i m e start\_time start_time e n d t i m e end_time endtime

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

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

AC代码:

#include <cstdio>
#include <algorithm>

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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值