每日c/c++题 备战蓝桥杯(小球反弹)[运动分解求解,最大公约数gcd]

试题B: 小球反弹题解

​​​​​​​​​​

❌错解分析

部分同学可能会尝试直接模拟每次碰撞的坐标变化,直到坐标回归原点。但这种方法存在明显缺陷:

  1. 实现过程繁琐,需处理大量碰撞计算
  2. 碰撞点坐标可能为浮点数,在非常多次碰撞后会产生显著精度损失

✅正解思路

|运动分解分析法|

核心公式

S = t × V 合 S = t \times V_{合} S=t×V合

其中:

  • t t t 为小球返回原点所需总时间
  • V 合 V_{合} V合 为合速度
  • S S S 为题目要求的总路程

这里的 V 合 V_{合} V合 可以直接用 d x dx dx 和 d y dy dy 合成,易求得,所以只需要探讨 t t t 怎么求即可

运动分解

将运动分解为x、y两个正交方向:

  1. x方向经过 p p p个完整来回( 2 p 2p 2p次横跨)
  2. y方向经过 q q q个完整来回( 2 q 2q 2q次纵跨)

需要注意的是,题目给的分速度是比的形式,但我们仍然可以看作dx是15,dy是17,因为以宏观来看,速率不影响小球经过了几个来回,总路程也不会因为速率的变化而改变

那么我们可以得到下面的式子,其中 x x x 是长方形的长, y y y 是长方形的宽
关键方程
{ t ⋅ d x = 2 p ⋅ x t ⋅ d y = 2 q ⋅ y \begin{cases} t \cdot dx = 2p \cdot x \\ t \cdot dy = 2q \cdot y \end{cases} {t⋅dx=2p⋅xt⋅dy=2q⋅y

比例关系

通过方程相除消元得到:
p q = y ⋅ d x x ⋅ d y \frac{p}{q} = \frac{y \cdot dx}{x \cdot dy} qp=x⋅dyy⋅dx

最小解推导

事实上,我们可以把 p = y ∗ d x p = y*dx p=y∗dx, q = x ∗ d y q = x*dy q=x∗dy,因为在这个情况下,等式也成立,也就是说小球依然是回到了原点,只不过不知道是第几次回到原点

我们以宏观的角度看,当上式的右边的分子分母为最简的时候,就是小球第一次回到原点的情况

那么现在的工作就是求等式右边分子分母的最大公约数的问题了

设:
p = y ⋅ d x gcd ⁡ ( y ⋅ d x , x ⋅ d y ) q = x ⋅ d y gcd ⁡ ( y ⋅ d x , x ⋅ d y ) \begin{aligned} p &= \frac{y \cdot dx}{\gcd(y \cdot dx, x \cdot dy)} \\ q &= \frac{x \cdot dy}{\gcd(y \cdot dx, x \cdot dy)} \end{aligned} pq=gcd(y⋅dx,x⋅dy)y⋅dx=gcd(y⋅dx,x⋅dy)x⋅dy

此时 p p p和 q q q为满足比例关系的最小整数解

总时间计算

代入任意方向方程求时间:
t = 2 p ⋅ x d x = 2 q ⋅ y d y t = \frac{2p \cdot x}{dx} = \frac{2q \cdot y}{dy} t=dx2p⋅x=dy2q⋅y

总路程计算

S = t ∗ d x 2 + d y 2 S = t * \sqrt{dx^2 + dy^2} S=t∗dx2+dy2

算法实现步骤

  1. 计算 y ∗ d x y*dx y∗dx 和 x ∗ d y x*dy x∗dy 的最大公约数 t e m tem tem
  2. 代入公式计算最小回归时间 t t t
  3. 输出结果保留2位小数

方法优势

  1. 规避浮点运算:全程使用整数运算,彻底消除精度误差
  2. 时间复杂度 O ( 1 ) O(1) O(1):仅需计算最大公约数(GCD),效率极高

代码

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
int gcd(int x,int y)
{
    int tem=x%y;
    while(x%y)
    {
        x =  y;
        y = tem;
        tem = x%y;
    }
    return y;
}
int main()
{
    int dx=15,dy=17,x=343720,y=233333;
    int p,q;
    p = y*dx;
    q = x*dy;
    int tem = gcd(p,q);
    p /= tem;
    q /= tem;
    int t = 2*p*x/dx;
    double ans = t * sqrt(15*15+17*17);
    printf("%.2lf", ans);
    return 0;
}

输出结果

1100325199.77

复杂度分析

  • 时间复杂度: O ( log ⁡ ( min ⁡ ( y d x , x d y ) ) ) O(\log(\min(ydx, xdy))) O(log(min(ydx,xdy)))(辗转相除法求gcd)
  • 空间复杂度: O ( 1 ) O(1) O(1)

注意事项

  • 注意处理浮点数输出精度
  • 确保使用64位双精度浮点数存储结果
  • 特判输入为0的情况(但题目保证输入为正整数)

总结

通过上述方法,我们可以准确计算出小球运动的总路程,并保留两位小数作为最终答案。这种方法避免了浮点数精度损失的问题,同时简化了计算过程,提高了效率。

相关推荐
玖釉-21 小时前
C++ 中的矩阵介绍:以二维矩阵查找为例
c++·windows·算法·矩阵
ECT-OS-JiuHuaShan21 小时前
存在是微分张量积,标量是参数但不可能是本质。还原论泛化,是语义劫持和以偏概全的逻辑谋杀伪科学庞氏骗局
数据库·人工智能·算法·机器学习·数学建模
CQU_JIAKE21 小时前
5.22【A】
算法
red_redemption21 小时前
自由学习记录(191)
学习
j_xxx404_21 小时前
Linux线程:从内存分页机制(Page Table/TLB/Page Fault)彻底读懂 Linux 线程本质
linux·运维·服务器·开发语言·c++·人工智能·ai
小新同学^O^21 小时前
OpenClaw 数据采集工具新手入门指南
python·学习·openclaw·纯ai文
2301_7890156221 小时前
C++_string增删查改模拟实现
java·开发语言·c++
lzp079121 小时前
基于多模态视觉模型和图文向量模型的工业图像知识库研究与应用(伍)
数据库·学习·neo4j
学习,学习,在学习21 小时前
Qt 串口通讯架构
开发语言·c++·qt·架构·qt5
2601_9578822421 小时前
多账号流量内容运营的数据归因与ROI优化:从经验驱动到算法决策的技术转型
算法·产品运营·内容运营