day1刷题打卡 | 豆包MarsCode AI刷题

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

问题描述

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

输入描述

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

输出描述

输出从 xy 所需的最小步数。


测试样例

样例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

思路

首先处理特殊情况,x和y距离如果是0或1,直接返回

然后模拟情况,如下(orz

距离 步数变化 最小步数
0 0 0
1 1 1
2 1 1 2
3 1 1 1 3
4 1 2 1 3
5 1 2 1 1 4
6 1 2 2 1 4
7 1 2 2 1 1 5
8 1 2 2 2 1 5
9 1 2 3 2 1 5
10 1 2 3 2 1 1 6
... ... ...
13 1 2 3 3 2 1 1 7
... ... ...
20 1 2 3 4 4 3 2 1 8

暴力

根据规律,其实就是一个等差数列, <math xmlns="http://www.w3.org/1998/Math/MathML"> S n = n a 1 + n ( n − 1 ) d 2 S_n=na_1+\frac{n(n-1)d}{2} </math>Sn=na1+2n(n−1)d,所以可以先遍历求出步长最大值a,对于最大步长的预设值,假设刚好是一个回文的字符串,那么最大步长范围为 <math xmlns="http://www.w3.org/1998/Math/MathML"> a ≈ ( a + 1 ) a 2 ∗ 2 ≈ 步长和 a \approx \sqrt{\frac{(a+1)a}{2}*2}\approx \sqrt{步长和} </math>a≈2(a+1)a∗2 ≈步长和 ,然后对剩余步数来进行遍历

  • 按规律等差数列求和左右两边已走步数 <math xmlns="http://www.w3.org/1998/Math/MathML"> a + a ( a − 1 ) 2 = a 2 + a 2 = a ( a + 1 ) 2 ⇒ a ( a + 1 ) 2 + a ( a − 1 ) 2 a+\frac{a(a-1)}{2} = \frac{a^2+a}{2}=\frac{a(a + 1)}{2}\Rightarrow \frac{a(a+1)}{2}+\frac{a(a-1)}{2} </math>a+2a(a−1)=2a2+a=2a(a+1)⇒2a(a+1)+2a(a−1)
  • 剩余步数: <math xmlns="http://www.w3.org/1998/Math/MathML"> r e s = d i s t − c n t res = dist-cnt </math>res=dist−cnt,这是就只要考虑剩下步数是直接用最大的步长还是用1来填充

简化

因为这个问题是求出最小步数,可以把问题简化为

  • 对于能够用等差数列求和的,步数为 <math xmlns="http://www.w3.org/1998/Math/MathML"> a + ( a − 1 ) = 2 a + 1 a + (a - 1)=2a+1 </math>a+(a−1)=2a+1
  • 根据上面讲述的a和步长和的关系,可以求出剩余步数为 <math xmlns="http://www.w3.org/1998/Math/MathML"> d i s t − a ∗ a dist-a*a </math>dist−a∗a,然后就要考虑补充1还是补充a
    1. 补充a

      说明此时剩余步数是a的倍数,补充a的步数为 <math xmlns="http://www.w3.org/1998/Math/MathML"> 剩余步数 a \frac{剩余步数}{a} </math>a剩余步数

    2. 补充1

      补充1不补充a说明a不能整除剩余步数,所以此时看余数就是补充1的步数数量

python 复制代码
def solution(x_position, y_position):
    dist = abs(x_position - y_position)
    if dist == 0:
        return 0
    elif dist == 1:
        return 1
    a = math.isqrt(dist)
    cnt = (dist - a * a) // a
    if (dist - a * a) % a:
        cnt += 1
    return cnt + 2 * a - 1

对步长递增取值和递减取值的思考

根据题目要求每步的移动范围是上一步的 -1+0+1 首末两步的步长必须是 1。求从 xy 的最少步数这两个条件进行模拟,可以看出需要使用等差数列来作为解题的核心。

条件:最小步数 <math xmlns="http://www.w3.org/1998/Math/MathML"> → \rightarrow </math>→步长尽可能的大,所以在移动范围的限制下,递增可以最快的将步数达到需求,同时考虑到最后一步为1,那么最后一步和递增最大点之间应该是0或者-1的关系,可以将0的插入思考全部放在递减部分,那么0怎么插入递减的步数中?选择范围为最大步长到1,如果不使用最大步长a,那么可能剩余的数为 <math xmlns="http://www.w3.org/1998/Math/MathML"> [ 1 , a − 1 ] [1,a-1] </math>[1,a−1]之间,这时候0可以插入中间满足要求的数,使取值在 <math xmlns="http://www.w3.org/1998/Math/MathML"> [ 1 , a − 1 ] [1,a-1] </math>[1,a−1]的这个数值加上后总步数为x和y的距离

相关推荐
Grin16 天前
寻找最大葫芦 | 豆包MarsCode AI刷题
青训营笔记
用户73378550925918 天前
后端笔记 | go语言进阶与依赖管理
青训营笔记
用户7056153326119 天前
刷题心得(三)| 豆包MarsCode AI刷题
青训营笔记
Damony1 个月前
Chain of Thought(CoT)和Tree of Thoughts(ToT)| 豆包MarsCode AI刷题
青训营笔记
Find4 个月前
MaxKB 集成langchain + Vue + PostgreSQL 的 本地大模型+本地知识库 构建私有大模型 | MarsCode AI刷题
青训营笔记
理tan王子4 个月前
伴学笔记 AI刷题 14.数组元素之和最小化 | 豆包MarsCode AI刷题
青训营笔记
理tan王子4 个月前
伴学笔记 AI刷题 25.DNA序列编辑距离 | 豆包MarsCode AI刷题
青训营笔记
理tan王子4 个月前
伴学笔记 AI刷题 9.超市里的货物架调整 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵4 个月前
分而治之,主题分片Partition | 豆包MarsCode AI刷题
青训营笔记
三六4 个月前
刷题漫漫路(二)| 豆包MarsCode AI刷题
青训营笔记