计算从位置x到y的最小步数 | 豆包MarsCode AI刷题

77 阅读4分钟

计算从位置x到y的最小步数

问题描述

小F正在进行一个 AB 实验,需要从整数位置 x 移动到整数位置 y。每一步可以将当前位置增加或减少,且每步的增加或减少的值必须是连续的整数(即每步的移动范围是上一步的 -1+0 或 +1)。首末两步的步长必须是 1。求从 x 到 y 的最少步数。

输入描述

输入包含两个整数 x 和 y,表示起始位置和目标位置。

输出描述

输出从 x 到 y 所需的最小步数。

思路分析

一般来说,这是典型的最优化问题,常用贪心算法或动态规划来解决。但是实现动态规划需要一定的编程基础,对于动态规划,直接使用Marscode解决得出的代码可读性不高,当程序输出结果不相符时,对代码的修正对于真小白来说就不太友好。所以我们可以考虑先对问题进行数学处理。 阅读题干,决定x到y的距离实际上是两个数的差值(下文对此统称查只能)。从最基本的算起,注意到首末两步步长必须为1,且每步应该是连续的整数。对于最优的理想情况,不难想到应该是“12321”或“123321”这种由两个公差为1的等差数列的对称结构组成,但事实并不总是如此,因为只是这样特殊的“回文数”显然不够满足任意差值的最优步数求解。 观察发现,在差值为9=1+2+3+2+1时,最优步数就是5,当差值为10时,可以看作是9+1,这中的1可以跟在123321的前面或后面,以此类推,11=9+2,2可以跟在任意2的后面。实际上,这个操作可以持续到12=9+3,差值在(9,12],最优步数都是6,当差值为13时,就必须多添一项,直到12+4(放在123后面形成1234321)。 进行到这里我们可以归纳了,在特定的区间内,区间的数都可以用上面的操作使得最优步数都与右端点最优步数相同,这里的右端点的数,都应该可以拆分成“1+2+3+2+1”或“1+2+3+3+2+1”这种由两个公差为1的等差数列的对称结构。 我们可以用三角数阵直观构建这种端点数:

微信图片_20241115153405.png不难发现,所谓的端点数实际上是这个数阵中每行的和,这个和是跟每一行的项数n一一对应的(实际上,项数就是在上列和与此列和左开右闭区间内的差值对于的x到y的最优步数),至此,我们就可以构建出“最优步长表”,通过差值的对号入座直接输出最优结果。

代码实现

    sum_val = 0
    for char in row:
        sum_val += int(char)
    return sum_val

def generateFn(n):
    Fn = []
    for i in range(n):
        half = (i + 1) // 2
        row = [str(j + 1) for j in range(half)] + [str(i + 1 - j) for j in range(half, i + 1)]
        Fn.append(triangleRowSum(row))
    return Fn

def solution(x_position, y_position):
    if x_position == y_position:
        return 0
    Z = abs(x_position - y_position)
    Fn = generateFn(1000)
    n = -1
    for i, value in enumerate(Fn):
        if n == -1 and value >= Z:
            n = i + 1
    return n

if __name__ == "__main__":
    print(solution(12, 6) == 4)
    print(solution(34, 45) == 6)
    print(solution(30, 50) == 8)
    print(solution(0, 0) == 0)

解释

1,我们可以优先构造“最优步长表”,从1开始,下一行的和就是这一行和加上行数,这里为了尽可能覆盖更多的差值,构造到1000行,并把结果存储在Fn中,我们可用用Marscode帮我们解决这段代码。 2,然后对每行求和(此部分在代码前端) 3,最后判断差值,这里只需要额外注意x=y时应返回步数0这种边界情况,这样,我们就用了比较巧妙的方式,避开动态规划解决了这个问题。

总结

1,如果对问题进行充分的数学整理和归纳,可以让代码的实现更简单更容易,可以降低代码的编写门槛。 2,在此代码中,我们应用了多个函数再统一整理成最终结果,帮助构建代码编写的“工程意识”。 3,我们在这里先构造了“最优步长表”,这为后续处理数据提供了充分便捷性和高效性。