1 条题解

  • 0
    @ 2026-5-18 17:08:05

    B. Robot Program 详细题解

    问题理解

    我们有一个机器人在数轴上运动,初始位置为 xxx0x \neq 0),有一条长度为 nn 的指令序列 ss(由 LLRR 组成)。

    机器人按顺序执行指令(每秒一条),但有一个关键规则: 每当机器人到达位置 00 时,指令计数器立即重置,即重新从 ss 的第一条指令开始执行。

    如果机器人执行完所有 nn 条指令后,当前位置不是 00,它就停止运行。

    我们需要计算在接下来的 kk 秒内,机器人进入 00 点的次数。

    注意:“进入”意味着到达 00 点的那一瞬间算一次,包括初始时刻吗?
    根据题意,机器人从 xxx0x \neq 0)开始,所以初始不在 00。第一次进入 00 是在某次移动之后。


    核心观察

    这个问题可以分解成几个阶段:

    阶段 1:第一次到达 00

    从初始位置 xx 出发,按顺序执行指令,直到第一次到达 00 点。

    设经过 t1t_1 秒(即执行了 t1t_1 条指令)后,机器人第一次到达 00

    如果在整个第一轮执行中从未到达 00,那么:

    • 执行完 nn 条指令后,机器人必然停在某个非零位置
    • 因为没到过 00,所以不会重置,之后就没有指令可执行了
    • 因此机器人会在 nn 秒后停止,之后 kk 秒内不会再动
    • 答案就是 00(因为从未进入 00

    所以首先要检查:是否存在 t1t_1 使得 1t1n1 \le t_1 \le n,并且执行前 t1t_1 条指令后位置变为 00


    阶段 2:重置后的循环行为

    一旦机器人第一次到达 00,它会立即重置指令指针,从 ss 的第一条指令开始重新执行。

    此时机器人在 00 点,执行一轮完整的 nn 条指令后,它会到达某个新的位置,记作 dddd 是执行完整个 ss 后的位移,即 RR 的数量减去 LL 的数量)。

    那么从 00 出发,执行一轮 nn 条指令的路径如下:

    • 00 开始
    • 执行第 11 条指令,位置变为 p1p_1
    • 执行第 22 条指令,位置变为 p2p_2
    • ...
    • 执行第 nn 条指令,位置变为 dd

    注意:在这 nn 步过程中,可能会多次经过 00 点。
    这些经过 00 的时刻(除了起点 00 本身)也是“进入 00 点”的事件。


    阶段 3:周期重复

    00 开始执行完一轮 nn 条指令后:

    • 如果 d=0d = 0,那么机器人在一轮结束后回到 00,下一轮又从 00 开始,行为完全重复
    • 如果 d0d \neq 0,那么一轮结束后机器人在 dd(非零),然后因为没有到达 00(因为结束位置不是 00),所以不会重置,机器人停止

    等等——这里要小心!

    根据规则:只有到达 00 时才重置
    如果一轮结束时位置是 d0d \neq 0,那么:

    • 执行完第 nn 条指令后,机器人在 dd,不是 00
    • 没有触发重置
    • 没有更多指令可执行(因为执行完了整个序列)
    • 所以机器人停止

    这意味着:如果机器人从 00 出发执行一轮后没有回到 00,那么它只会执行这一轮,然后停止。

    因此,如果要产生多次进入 00 的循环,必须满足 d=0d = 0,即一轮的净位移为 00


    更准确的分析

    实际上,标程采用了一种更巧妙的方法:

    1. 先尝试到达 00
      xx 开始模拟,直到要么到达 00,要么用完 nn 条指令且没到 00
      如果 nn 条指令用完还没到 00,答案就是 00

    2. 如果到达了 00
      设到达 00 用了 t1t_1 秒。此时:

      • 已经进入 00 一次(计入答案)
      • 剩余时间 k=kt1k' = k - t_1
    3. 重置后,从 00 开始
      00 开始执行指令序列,找出第一次(非起点)到达 00 的位置。
      设从 00 出发,经过 cc 条指令后第一次回到 00cc 可能在 11nn 之间,也可能不存在)。

      如果存在这样的 cc,那么:

      • cc 秒,机器人就会进入 00 一次
      • 在剩余 kk' 秒中,这样的周期有 kc\left\lfloor \frac{k'}{c} \right\rfloor
      • 加上之前的一次,总共 1+kc1 + \left\lfloor \frac{k'}{c} \right\rfloor

      如果不存在这样的 cc(即从 00 出发后永远不会再回到 00),那么只有第一次到达 00 的那一次,答案为 11


    标程解析

    标程的代码逻辑如下:

    li n, x, k;
    cin >> n >> x >> k;
    string s;
    cin >> s;
    // 第一阶段:从 x 出发,尝试到达 0
    for (int i = 0; i < n; ++i) {
        x += (s[i] == 'L' ? -1 : +1);
        --k;           // 消耗 1 秒
        if (!x) break; // 到达 0,停止模拟
    }
    li ans = 0;
    if (!x) {  // 如果成功到达 0
        ans = 1;  // 第一次进入 0
        // 第二阶段:从 0 开始,找回到 0 的最小周期
        for (int i = 0; i < n; ++i) {
            x += (s[i] == 'L' ? -1 : +1);
            if (!x) {
                ans += k / (i + 1);  // 剩余时间能完成多少个完整周期
                break;
            }
        }
    }
    cout << ans << '\n';
    

    关键点

    • 第一个循环模拟到第一次到达 00,同时消耗时间
    • 如果成功到达,ansans 初始为 11xx 此时为 00
    • 第二个循环从 00 开始,找第一次回到 00 的位置(步数为 i+1i+1
    • 一旦找到,用剩余时间 kk 除以周期长度,得到额外进入次数
    • 注意:第二个循环开始时 xx 已经是 00,所以执行第一条指令后 xx 变成 ±1\pm 1,然后继续

    公式总结

    设:

    • t1t_1 = 从 xx 到第一次到达 00 所需的步数(如果存在)
    • 如果 t1t_1 不存在,答案为 00
    • 否则,设 cc = 从 00 出发后,第一次回到 00 所需的步数(1cn1 \le c \le n,如果存在)
    • 如果 cc 不存在,答案为 11
    • 如果 cc 存在,答案为 1+kt1c1 + \left\lfloor \frac{k - t_1}{c} \right\rfloor

    其中 kk 是总时间,实际剩余时间在模拟中已经通过 --k 处理,所以代码中直接用 k / (i+1)


    复杂度分析

    • 每个测试用例模拟最多 2n2n 步(两次遍历 ss
    • 所有测试用例的 nn 之和不超过 2×1052\times10^5,所以总复杂度 O(n)O(\sum n)
    • 完全满足时间限制 22

    示例验证

    以第二个示例为例: n=2,x=1,k=8,s=RLn=2, x=-1, k=8, s=\text{RL}

    第一阶段

    • 初始 x=1x=-1k=8k=8
    • 指令1: RRx=1+1=0x = -1+1 = 0,到达 00k=7k=7,停止 t1=1t_1=1ans=1ans=1

    第二阶段

    • x=0x=0 开始(代码中 xx 已被重置为 00
    • 指令1: RRx=1x=1(不是 00
    • 指令2: LLx=0x=0,到达 00,步数 i+1=2i+1=2
    • ans=1+7/2=1+3=4ans = 1 + \lfloor 7/2 \rfloor = 1+3 = 4

    总结

    这道题的关键在于:

    1. 区分“第一次到达 00”和“从 00 出发后的循环周期”
    2. 理解重置规则导致只有净位移为 00 才能产生多次进入
    3. 通过模拟找到最小周期 cc,然后用除法计算完整周期数

    标程通过两遍遍历巧妙地解决了问题,避免了显式处理循环和净位移的复杂判断。

    • 1

    信息

    ID
    7210
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者