计算最小步长丨豆包MarsCodeAI刷题

如何解决计算从位置 x 到 y 的最少步数?

先分析问题描述

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

我的思考:打个比方,我生活在一个数轴上,我是小帅,要和小美见面,我们之间有一段距离,去见小美的规则是,从第一步开始就要计算我与小美的距离还有多远,不能把步子走大了 ,减不下速,错过了小美。而我有什么工具能帮助我,及时变速 来确保能够准确的到达小美的位置呢,我们有三个望远镜,第一个望远镜是增距望远镜 ,它可以在我们现走步长基础上加1 去看小美与我们的距离是大于该距离、还是等于该距离、还是小于该距离,第二个望远镜是普通望远镜 ,它可以在我们现走步长基础上保持原有长度 去看小美与我们的距离是大于该距离、还是等于该距离、还是小于该距离,而第三个望远镜是减距望远镜 ,它可以在我们现走步长基础上减1去看小美与我们的距离是大于该距离、还是等于该距离、还是小于该距离,有了这三个工具,我们就能进行更快的判断小美与我们的距离以及我们速度是否足够准确的变速到达她的位置。

那么,有了这三个工具,该如何使用呢?

来看看问题的要求。

来看输入描述

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

得先有我和她的位置坐标,计算我们之间的距离,由于距离是正值 ,所以需要用abs函数来去取绝对值。

这是输入情况。

用代码表示一下

js 复制代码
def solution(x_position, y_position):
     # 调用calculate_min_step_size函数,并获取步数计数
    step_count = calculate_min_step_size(x_position, y_position)
     # 返回步数计数
    return step_count`

再看输出描述

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

既然我们要以最快最高效的方式见到小美,就意味着我们能快则快 ,能增加一,就增加一,当这三个望远镜都还看不到小美的时候,就一直把步长增加一。

而另外的情况,我统一把他们列出来了。

| 情况详细说明 | 增距望远镜 | 普通望远镜 | 减距望远镜 | 怎么走 |

| 是否看见小美 | 远得看不见 | 远得看不见 | 远得看不见 | 步长加1 |

| 是否看见小美 | 刚好看见了 | 远得看不见 | 远得看不见 | 步长加1 |

| 是否看见小美 | 超过小美了 | 远得看不见 | 远得看不见 | 步长不变 |

| 是否看见小美 | 超过小美了 | 刚好看见了 | 远得看不见 | 步长不变 |

| 是否看见小美 | 超过小美了 | 超过小美了 | 远得看不见 | 步长减1 |

| 是否看见小美 | 超过小美了 | 超过小美了 | 刚好看见了 | 步长减1 |

| 是否看见小美 | 超过小美了 | 超过小美了 | 超过小美了 | 刚好遇见你 |

也就是说,我们在尽可能的在最快速度范围内维持一个最大的速度来去奔向小美,确保能够实现用最少的步数来走完我们之间的距离。

OK,思路清晰,开始写代码!

初始步长,计数值,步数值和均为0,原差值就是我们之间距离的作差取绝对值。

js 复制代码
# 定义calculate_min_step_size函数
def calculate_min_step_size(x_position, y_position):
    # 初始化参数
    step_size = 0  # 步长
    step_count = 0  # 步数计数
    step_value_sum = 0  # 步数值和
    original_difference = abs(x_position - y_position)  # 原差值

然后,就需要把这三个望远镜用公式表达出来。

导入循环。

js 复制代码
    # 循环,直到步数值和等于或超过原差值
    while step_value_sum < original_difference:

看看我们之间还有多少距离?

js 复制代码
        计算剩余前进值
        remaining_value = original_difference - step_value_sum

第一个望远镜是增距的。所以从步长加1一直逐1递减到1为止。这是一个等差数列,求和用首末项乘项数并除以2来进行计算。

js 复制代码
        increased_steps = (((step_size + 1) + 1) * (step_size + 1)) // 2

第二个望远镜是原有步长保持不变的。所以从步长原有值一直逐1递减到1为止。

js 复制代码
        unchanged_steps = ((step_size + 1) * step_size) // 2

第三个望远镜是减距的。所以从步长减1开始一直逐1递减到1为止。

js 复制代码
        decreased_steps = ((step_size + 1 - 1) * (step_size - 1)) // 2

之后,根据表格中的七种情况,进行大小判断:

js 复制代码
        # 判断条件并执行相应的操作
        if increased_steps < remaining_value and unchanged_steps < remaining_value and decreased_steps < remaining_value:
            step_size += 1
        elif increased_steps == remaining_value and unchanged_steps < remaining_value and decreased_steps < remaining_value:
            step_size += 1
        elif increased_steps > remaining_value and unchanged_steps < remaining_value and decreased_steps < remaining_value:
            step_size = step_size
        elif increased_steps > remaining_value and unchanged_steps == remaining_value and decreased_steps < remaining_value:
            step_size = step_size
        elif increased_steps > remaining_value and unchanged_steps > remaining_value and decreased_steps < remaining_value:
            step_size -= 1
        elif increased_steps > remaining_value and unchanged_steps > remaining_value and decreased_steps == remaining_value:
            step_size -= 1
        elif increased_steps > remaining_value and unchanged_steps > remaining_value and decreased_steps > remaining_value:
            break

可别忘了在循环结束时,还要更新步数计数和步数值和哦。

bash 复制代码
        # 更新步数计数和步数值和
        step_count += 1
        step_value_sum += step_size

最后,结束循环后,再返回我们需要的步数计数值,大功告成。

bash 复制代码
    # 返回步数计数
    return step_count

可以看看整个流程。

graph TD A[开始] --> B[初始化:step_size=0,step_count=0,step_value_sum=0,original_difference=abs#x_position-y_position#] B --> C{step_value_sum < original_difference} C -->|是| D[计算remaining_value: original_difference - step_value_sum] D --> E[计算三种步数] E --> Q[计算三种步数 increased_steps=step_size+2再*step_size+1后//2] E --> R[计算三种步数 unchanged_steps=step_size+1再*step_size后//2] E --> T[计算三种步数 decreased_steps=step_size再*step_size-1后//2] Q --> P{判断七种情况} R --> P{判断七种情况} T --> P{判断七种情况} P --> F{remaining_value与increased_steps,unchanged_steps,decreased_steps的关系} F -->|1 小小小| G[step_size += 1] F -->|2 等小小| G F -->|3 大小小| I[step_size = step_size] F -->|4 大等小| I F -->|5 大大小| J[step_size -= 1] F -->|6 大大等| J F -->|7 大大大| K[结束循环] G --> L[step_count += 1] I --> L J --> L K --> C L --> M[step_value_sum += step_size] M --> C C -->|否| N[结束] N --> O[返回 step_count]

你是否有所收获,我大概是按照这样一个比较普通的判断思路来进行的,哪有还有问题,我积极听取意见并改进。

one more thing

做这道题,我刚开始只想求助AI,结果发现,他们的思路似乎已经陷入瓶颈,无法有所突破,于是我就想通过自己的纸上推演,一点点来去看这样的问题该如何用数学思路解决。

经过一晚上的思考,虽然是个简单题,参照了CSDN里部分同学提供的思路,我发现,这个最少步数的题目,其实最关键的,就是规则。

如果规则要求,增加二,减少二,不变,也许结果又与这种情况有了很大的不同,我知道计算机只能一步一步推理,所以我就把自己当做计算机,一步一步把思路理清楚,才发现,这规则原来是要求我对未来的步长走向进行预判,预判值的大小决定了我对步长下一步设定的变化方向。

这特别像人生,我们从过去的路中,吸取经验,但我们不能就沉浸于过去,而需要往前看未来的趋势,未来会如何变化,我们就要怎样去转变思路,调整自己的方向,每一步都只能改一个步长,是加速,还是减速,亦或者保持原速,都需要根据未来的目标随时调整,这算是一个比较有意思的收获。

而我在思考过程中,使用ai带给我的,其实是一种代码纠错的帮助机制,提供思路的辅助功能,更多的思考还是需要我来去进行,尤其是这里面的思维活动,是ai代替不了的。

相关推荐
柠檬柠檬4 小时前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记
用户529757993547220 小时前
字节跳动青训营刷题笔记2| 豆包MarsCode AI刷题
青训营笔记
clearcold1 天前
浅谈对LangChain中Model I/O的见解 | 豆包MarsCode AI刷题
青训营笔记
夭要7夜宵2 天前
【字节青训营】 Go 进阶语言:并发概述、Goroutine、Channel、协程池 | 豆包MarsCode AI刷题
青训营笔记
用户336901104442 天前
数字分组求和题解 | 豆包MarsCode AI刷题
青训营笔记
dnxb1232 天前
GO语言工程实践课后作业:实现思路、代码以及路径记录 | 豆包MarsCode AI刷题
青训营笔记
用户916357440952 天前
AI刷题-动态规划“DNA序列编辑距离” | 豆包MarsCode AI刷题
青训营笔记
热的棒打鲜橙2 天前
数字分组求偶数和 | 豆包MarsCode AI刷题
青训营笔记
JinY142 天前
Go 语言入门指南:基础语法和常用特性解析 | 豆包MarsCode AI刷题
青训营笔记