题目解析: 2. 计算位置 x 到 y 的最少步数 | 豆包MarsCode AI刷题

120 阅读3分钟

问题描述

AB 实验同学每天都很苦恼如何可以更好地进行 AB 实验,每一步的流程很重要,我们目标为了缩短所需的步数。

我们假设每一步对应到每一个位置。从一个整数位置 x 走到另外一个整数位置 y,每一步的长度是正整数,每步的值等于上一步的值 -1+0+1。求 xy 最少走几步。并且第一步必须是 1,最后一步必须是 1,从 xy 最少需要多少步。

样例说明

  • 整数位置 x12,另外一个整数位置 y6,我们需要从 x 走到 y,最小的步数为:1221,所以我们需要走 4 步。
  • 整数位置 x34,另外一个整数位置 y45,我们需要从 x 走到 y,最小的步数为:123221,所以我们需要走 6 步。
  • 整数位置 x50,另外一个整数位置 y30,我们需要从 x 走到 y,最小的步数为:12344321,所以我们需要走 8 步。

输入格式

输入包含 2 个整数 xy。(0<=x<=y<2^31

输出格式

对于每一组数据,输出一行,仅包含一个整数,从 xy 所需最小步数。

输入样例

12 6
34 45
50 30

输出样例

4
6
8

想法

用易懂、自然的思路来解这道题。

我们观察到所有情况都是类似于1,2,3,...,k,...,3,2,1(像一个山峰,我们称其为k峰,k是山峰顶点的海拔,每个点的海拔相加得到一个值sum); 但是有些距离的答案并不完全就是一个k峰,有点像在一个k峰的基础上再加了几步。

用贪心的思想,我们知道,如果要步数最少,就要让k峰够大,所以最后答案其实是sum值最接近xy距离的一个k峰加上了小于等于k的n步(n>=0),不必纠结这几步加入到序列里面的位置,这几步见缝插针到序列里面即可。

所以答案由两部分组成,k峰的宽度(2*k-1)+插入的n步。

n步如何求呢?同样是用贪心的思想,尽可能一步走k个距离,最后不够k个距离再补一步。所以:xy距离-sum=a*k+b,即n=a或n=a+1(如果b不为0,再补一步)。

代码

int solution(int xPosition, int yPosition) {
    //算距离
    int dis = abs(xPosition - yPosition);
    
    //特殊情况x和y重合
    if(dis == 0) return 0;
    
    //找到k值
    int top = sqrt(dis);
    
    //算要补大小为k的步子几步
    int extra_top = (dis - top * top) / top;
    
    //看最后还要不要补一步
    int extra_normal;
    if((dis - top * top) % top == 0)
        extra_normal = 0;
    else
        extra_normal = 1;
        
    //把走的所有步相加,返回
    return 2 * top - 1 + extra_top + extra_normal;
}