青训营入营活动主题3:主题 3:寻友之旅

81 阅读2分钟

当青训营遇上码上掘金

主题3:寻友之旅

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走)

请帮助小青通知小码,小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)

题意分析

分析题意,我们可以把题目抽象为:在一数轴上给定坐标A、B,目的是使得A经过一系列变换后变为B。 点A的坐标改变方式有两种:
1.使当前坐标x变为x+1或x-1。
2.使当前坐标变为x*2。
观察到这儿,我们可以发现这种变换方式与二进制操作有些类似。方式1在一个二进制的最低为加一或减一;方拾二是将一个二进制数整体向左移动一位。
因此我们的解题思路是将小青所在地点N的坐标A转换为二进制数,再通过二进制操作来使得A变为B。

具体分析

首先对于输入的坐标A、B我们可以得到三种情况:
1.A = B 意味着不需要操作,直接输出0即可。
2.A > B 这种情况下由于题目中公交车不可以向后走,我们只需要一直执行操作1,使得A = B,也就是输出A-B。
3.A < B 这种是需要解决的基本情况。考虑到A < B,则有A的二进制位数小于等于B的二进制位数。此时我们假设A二进制数为n,B二进制位数为M,在B的前n位于A的n位相同时,对于多出的每一位,我们可以将A向左移动一位进行补齐,同时在补齐的过程中若此时A已补0至B的第j位,那么在B的第j位为1的情况下,我们对A进行操作1即可一直保证A与B相同。
接下来讨论如何使得A的n位与B的前m位相同。我们可以将A与B的二进制数在数轴上表示的范围收尾相连视作一个环。那么A与B的最短距离即是我们想要的最少操作数。
考虑到实际上A与B并不能形成一个环,当A的前n位向上溢出时,会使得二进制数向前进一位。因此我们考虑的两个方向的距离变在A > B[0:n]时为 A - B[0:n] + 1 + B[n+1] 或 B[0:n+1] - A(多比较了一位);在A < B[0:n]时为 B[0:n] - A 或 A - B[0:n-1] + 1 + B[n] (少比较了一位) 。
最终我们只需要取两者之间的最小值即可。

总结

本题的解题思路是将两种操作转换为二进制表示,从而找到将A变为B的正确方式。但对于这种操作思路的最优性并没有详细分析,主要以“操作二执行的越多越好”的贪心思路为主。如果读者懂的话欢迎评论给出详细证明。