每日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的情况(但题目保证输入为正整数)

总结

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

相关推荐
汉克老师3 分钟前
GESP2025年3月认证C++五级( 第三部分编程题(2、原根判断))
c++·算法·模运算·gesp5级·gesp五级·原根·分解质因数
Amazing_Cacao5 分钟前
CFCA精品可可产区认证课程风土解析(美洲):打破风味堆叠的假象,建立时间轴上的层次展开阅读系统
学习
热心网友俣先生7 分钟前
2026年第二十三届五一数学建模竞赛C题各问题参考答案
数学建模
永远不会的CC18 分钟前
浙江华昱欣实习(4月23日~ 4月19日)
后端·学习
winner888121 分钟前
从零吃透C++命名空间、std、#include、string、vector
java·开发语言·c++
数据皮皮侠24 分钟前
上市公司创新韧性数据(2000-2024)|顶刊同款 EIR 指数
大数据·人工智能·算法·智慧城市·制造
爱上好庆祝25 分钟前
学习js的第五天
前端·css·学习·html·css3·js
WL_Aurora27 分钟前
Python 算法基础篇之链表
python·算法·链表
科研前沿35 分钟前
纯视觉无感解算 + 动态数字孪生:室内外无感定位技术全新升级
大数据·人工智能·算法·重构·空间计算
qiaozhangchi36 分钟前
求解器学习笔记
笔记·python·学习