题目
问题描述
小F正在进行一个 AB 实验,需要从整数位置 x 移动到整数位置 y。每一步可以将当前位置增加或减少,且每步的增加或减少的值必须是连续的整数(即每步的移动范围是上一步的 -1,+0 或 +1)。首末两步的步长必须是 1。求从 x 到 y 的最少步数。
输入描述
输入包含两个整数 x 和 y,表示起始位置和目标位置。
输出描述
输出从 x 到 y 所需的最小步数。
测试样例
样例1:
输入:
x_position = 12, y_position = 6
输出:4
样例2:
输入:
x_position = 34, y_position = 45
输出:6
样例3:
输入:
x_position = 50, y_position = 30
输出:8
样例4:
输入:
x_position = 0, y_position = 0
输出:0
题解
根据题目信息,我们知道有限制条件第一步和最后一步的步长都为1,并且要求最少步数。那么问题可以理解成一个简单的贪心问题。同时每步的增加或减少的值必须是连续的整数,故考虑等差数列求和公式有(首项+末项)* 系数/2。
我们再结合样例进行分析:
- 对于样例一:x和y之间的距离相差6,所以可以走1,2,2,1,共4步,即可到达y。
- 对于样例二:x和y之间的距离相差11,所以可以走1,2,2,3,2,1,共6步,即可到达y。
- 对于样例三:x和y之间的距离相差20,所以可以走1,2,3,4,4,3,2,1,共8步,即可到达y。
- 对于样例四:x和y之间的距离相差0,所以可以走0步,即可到达y。
这些样例给了我们很好的提示,那就是我们需要对题目进行分情况讨论,以获得各种可能情况的正确结果。
首先对于输入条件,分别考虑输入x<=y和x>y的两种情况,分别计算x和y之间的距离。
dis = 0
if x_position < y_position:
dis = y_position - x_position
else:
dis = x_position - y_position
然后我们计算项数,已知首项为1,那么末项一定等于项数,而距离dis可以理解成等差数列的和的二倍。
n_time = math.floor(math.sqrt(dis))
但这时获得的n_time并不是最终结果,因为还需要考虑余数问题。依旧需要进行分情况讨论。
ys = dis - n_time * (n_time + 1)
if ys <= 0:
return n_time * 2
elif ys <= n_time + 2:
return n_time * 2 + 1
else:
return n_time * 2 + 2
感受
这是一道比较简单的贪心问题,但是需要对所有的情况进行全面的考虑,才能获得正确的结果。也许我的做法并不是最简单的做法,欢迎指教。