1 条题解

  • 0
    @ 2025-4-9 20:43:39

    题意分析

    本题描述了在一个台球桌上,球从桌子正中心被击出,经过 ss 秒后回到击出点,期间在垂直边反弹 mm 次,在水平边反弹 nn 次。需要求出球的发射角度 AA(与水平方向的夹角,范围在 0 到 90 度之间)以及球的初速度。球与桌边的碰撞是完全弹性的,意味着球在平行于桌边的方向上的速度分量保持不变,且球的半径为零。输入包含多行,每行有五个非负整数 aabbssmmnn,输入以一行五个零结束。对于除最后一行外的每个输入行,输出一行包含两个精确到小数点后两位的实数,分别是角度 AA 的度数和球的速度(英寸/秒)。

    解题思路

    1. 计算球在水平和垂直方向移动的总距离
      • 球在水平方向移动的总距离为 nan * a
      • 球在垂直方向移动的总距离为 mbm * b
    2. 计算球移动的总路程
      • 根据勾股定理,球移动的总路程 dd(na)2+(mb)2\sqrt{(n * a)^2 + (m * b)^2}
    3. 计算球的速度
      • 速度 vv 等于总路程除以时间,即 v=d/sv = d / s
    4. 计算发射角度
      • 发射角度 AA 的正切值为垂直方向移动的总距离除以水平方向移动的总距离,即 tan(A)=mbna\tan(A) = \frac{m * b}{n * a}
      • 通过 atanatan 函数求出弧度值,再将弧度值转换为角度值。

    示例代码

    #include <iostream>
    #include <cmath>
    #include <iomanip>
    using namespace std;
    
    int main() {
        int a, b, s, m, n;
        while (cin >> a >> b >> s >> m >> n) {
            if (a == 0 && b == 0 && s == 0 && m == 0 && n == 0) {
                break;
            }
            double vx = (m * a) / (double)s;
            double vy = (n * b) / (double)s;
            double speed = sqrt(vx*vx + vy*vy);
            double angle_deg;
            
            if (vx == 0) {
                angle_deg = (vy == 0) ? 0.0 : 90.0;
            } else if (vy == 0) {
                angle_deg = 0.0;
            } else {
                angle_deg = atan(vy / vx) * 180.0 / M_PI;
            }
            
            cout << fixed << setprecision(2) << angle_deg << " " << speed << endl;
        }
        return 0;
    }
    

    代码解释

    1. 输入处理:使用 whilewhile 循环读取输入,直到输入为五个零为止。
    2. 距离计算:计算球在水平和垂直方向移动的总距离,以及总路程。
    3. 速度计算:根据总路程和时间计算球的速度。
    4. 角度计算:通过 atanatan 函数计算发射角度的弧度值,再将其转换为角度值。
    5. 输出结果:使用 std::fixedstd::fixedstd::setprecision(2)std::setprecision(2) 确保输出结果精确到小数点后两位。
    • 1

    信息

    ID
    1641
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    3
    已通过
    1
    上传者