计算位置x到y的最少步数
AB 实验同学每天都很苦恼如何可以更好地进行 AB 实验,每一步的流程很重要,我们目标为了缩短所需的步数。
我们假设每一步对应到每一个位置。从一个整数位置 x 走到另外一个整数位置 y,每一步的长度是正整数,每步的值等于上一步的值 -1, +0,+1。求 x 到 y 最少走几步。并且第一步必须是 1,最后一步必须是 1,从 x 到 y 最少需要多少步。
样例说明
- 整数位置
x为12,另外一个整数位置y为6,我们需要从x走到y,最小的步数为:1,2,2,1,所以我们需要走4步。 - 整数位置
x为34,另外一个整数位置y为45,我们需要从x走到y,最小的步数为:1,2,3,2,2,1,所以我们需要走6步。 - 整数位置
x为50,另外一个整数位置y为30,我们需要从x走到y,最小的步数为:1,2,3,4,4,3,2,1,所以我们需要走8步。
输入格式
输入包含 2 个整数 x,y。(0<=x<=y<2^31)
输出格式
对于每一组数据,输出一行,仅包含一个整数,从 x 到 y 所需最小步数。
输入样例
12 6
34 45
50 30
输出样例
4
6
8
解题思路!!!非原创(一点小地方做了改动,方便自己理解,所以写个文章,不一定正确)
要解决这个问题,我们需要理解步长变化规则,并设计一种策略,既能快速覆盖距离,又能满足步长变化的限制。一下是详细的思路分析。
1.距离计算
首先,计算总距离 diff=|y-x|。
2.步长变化规则
.起始步长: 第一步必须是1
.步长变化:
每一步的步长等于上一步的值 -1, +0,+1
.结束步长: 最后一步必须是1
3.步长序列的特性
为了最小化步数,我们希望步长尽可能地快速增加,以覆盖更多的距离,然后再逐步减少步长,以满足最后一步必须为1的条件。这类似于形成一个“山峰”形状的步长序列。
4. 最大步长k的确定
假设步长序列的最大步长为k,那么序列大致会是1, 2, 3, ..., k, ..., 3, 2, 1。需要确定k的值,使得步长序列的总和尽可能接近但不超过diff。
为了估算k,我们可以利用数学中的等差数列求和公式:
S= 1 + 2 + 3 + ··· + k = k(k + 1)/2
这个公式表示步长从1增加到k时的总距离。如果我们希望总距离接近diff,则可以近似认为: k^2 == diff, 因此,k的值可以通过计算k = sqrt(diff)来估算。
5. 计算最少步数
根据最大步长k,最少步数可以通过以下公式计算:
-
如果
k^2 < diff:
这里的情况是
1 + 2 + 3 + ··· + k + k-1 + k-2 + ··· + 2 + 1 < diff
且
1 + 2 + 3 + ··· + k + k+1 + k + k-1 + ··· + 2 + 1 > diff
范围是 1 到 2k,对应 1 到 2 个数,这些数可以是 1 到 k 中的任意数,只要满足最后的序列相加等于diff。- 需要额外的步数来覆盖剩余的距离
diff - k^2 - 额外步数
- 补充 最多+2步
- (k+1)^2-k^2=2k+1 距离都为整数,则额外步数最多为
2k,需要两步 - 即:当
(diff-k^2)<=k时extraSteps=1elseextraSteps=2; - 总步数
n = 2k - 1 + extraSteps
- 需要额外的步数来覆盖剩余的距离
-
否则:
- 总步数
n = 2k - 1
- 总步数
6. 特殊情况处理
- 当
diff = 0:起点和终点相同,不需要任何步数,n = 0
算法实现
#include <iostream>
#include<cmath>
int solution(int x, int y) {
// Please write your code here
int minSteps;
if(x>y)
{int temp=x;
x=y;
y=temp;
}
int diff=y-x;
if(diff==0) return 0;
int k=(int)sqrt(diff);
int KSqared =k*k;
int distance=diff-KSqared;
if(distance!=0)
{
if(distance<=k) return 2*k;
else return 2*k+1;
}
else return 2*k-1;
}
int main() {
// You can add more test cases here
std::cout << (solution(12, 6) == 4) << std::endl;
std::cout << (solution(34, 45) == 6) << std::endl;
std::cout << (solution(50, 30) == 8) << std::endl;
return 0;
}
原创作者:热的棒打鲜橙
链接:juejin.cn/post/742025…