1 条题解

  • 0
    @ 2026-5-3 21:19:17

    最简单的方法是直接进行广度优先搜索(BFS)。构建一个以数字为顶点、以操作能改变数字的边为有向边的图。我们可以注意到,将数字变得大于 2m2m 是永远不合理的,因此在给定的限制条件下,该图最多包含 21042 \cdot 10^4 个顶点和 41044 \cdot 10^4 条边,BFS 会非常快。

    然而,还有一种更快的解法。我们可以将问题反过来思考:从 mm 出发,使用“给数字加 11”和“若数字为偶数则除以 22”这两种操作,得到 nn

    假设在某个时刻,我们连续执行了两次类型 11 操作(即加 11),然后执行了一次类型 22 操作(即除以 22);但此时,如果先执行一次类型 22 操作再执行一次类型 11 操作,会得到相同的结果,而且操作序列比之前更短。这个推理意味着:在一个最优解中,只有当后续不再有类型 22 操作时,才会出现连续多于一次的类型 11 操作。也就是说,唯一有意义的情况是当 n<mn < m 时,我们只需将其增加到足够大。在此约束下,只有一种正确的操作序列:

    • 如果 nn 小于 mm,我们不断地加 11,直到它们相等;
    • 否则(n>mn > m),如果 nn 是偶数,则除以 22;如果是奇数,则先加 11 再除以 22

    这个序列的长度可以在 O(logm)O(\log m) 时间内计算出来。

    挑战:考虑一个更一般的问题:我们希望从 nn 得到 mm,使用两种操作“减去 aa”和“乘以 bb”。如果 aabb 互质,能否推广上述解法,在 O(logm)O(\log m) 时间内求出最少步数?如果 aabb 可能存在大于 11 的公因数,你又该怎么做?

    #include <iostream>
    int n,m,a;main(){std::cin>>n>>m;while(n<m)m%2?m++:m/=2,a++;std::cout<<a+n-m;}
    
    • 1

    信息

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