39 计算从位置x到y的最少步数 | 豆包Marscode Al刷题

73 阅读3分钟

题目描述

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

输入描述

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

输出描述

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

解题思路

这一题很容易走进一个误区:因为每下一步都可以选择比上多一步、少一步或不变,因此若一步一步进行讨论会因为这个随机性而使题目变得复杂。但是只要换一个思路,这道题就会简化许多。

首先注意到一点,这一道题其实只注重结果:步数最小,而并不注重过程。如若总步数一致,任意两步即使交换,只要满足题目所要求的相邻步长之差小于等于1,对结果也不会造成影响。

因此我们可以选用一种符合题目要求的特例情况来简化题目。在这里我使用的是阶梯模型。以步数为横坐标,步长为阶梯高度,相邻阶梯高度之差不得超过1,且该阶梯只有一个上升和一个下降,阶梯两端开始高度为1。在这种情况下,很明显这个模型是满足题目的约束条件的,而题目所求的问题就是阶梯高度之和为一定值(即y-x)时,使得阶梯长度最小。

对阶梯模型和题目要求进行分析。我们可以得到以下三个结论:

  1. 在阶梯高度之和为定值情况下,要使阶梯长度达到最小,则阶梯要尽可能高,也就是阶梯高度的最大值要达到最大,并且每一级阶梯都要尽可能的高;
  2. 因为已经简化了阶梯只有一个上升和一个下降,那么阶梯的升降就是对称的,即有多少级上升,就有多少级下降;
  3. 对于平级(也就是和相邻阶梯高度一致)阶梯,只要置于正确的高度区间内,无论是在上升段还是在下降段或是等高阶梯之间互相交换,都不会影响所求结果。

因此我的思路如下:

  1. 再次对阶梯进行简化,将所有平级阶梯置于下降段,上升段连续上升;
  2. 设最高阶梯高度为n,则上升段的阶梯高度和为1+2+3+...+n-1;由于下降段阶梯和上升段对称,则下降段阶梯高度也为1+2+3+...+n-1,一共为2(1+2+3+...+n-1);
  3. 用总高度减去升降必须有的阶梯高度,剩下的阶梯高度l逐一填入平级:若l>n,则在n-1高度阶梯之间添加l//n个n高度阶梯;否则,将n一步一步减1,不断以平级添入阶梯下降段内,直至l为0。

在实际的编程中,因为不知道最高阶梯高度n,所以需要一层一层减去升降段阶梯,再比较剩余阶梯是否还能满足一对升降段阶梯,直至无法满足,得到最高高度n,再从n逐步下降,尽可能把剩余阶梯高度用在高一点的阶梯上。

代码

def solution(x_position, y_position):
    # Please write your code here
    l=abs(y_position-x_position)
    max_step=0
    left=l
    while(left>=max_step*2):
        left-=max_step*2
        max_step+=1
    n=2*(max_step-1)
    while(left>0):
        if left>=max_step:
            left-=max_step
            n+=1
        else:
            max_step-=1
    return n
    



if __name__ == "__main__":
    #  You can add more test cases here
    print(solution(12, 6) == 4 )
    print(solution(34, 45) == 6)
    print(solution(50, 30) == 8)