题目的主要信息:

  • 一球从hh米高度自由落下,每次落地后反跳回原高度的一半再落下,求它在第55次落地时共经过了多少米?第55次返弹多高?
  • 精度保留到小数点后6位,输出去掉后面的0

方法一:过程模拟

具体做法:

我们遍历落地次数,第一次走过了落下高度这么多距离,然后弹起高度降低一半,然后走了弹起的高度这么多距离,完成一次循环,如果55个循环,累加距离,不断降低高度。需要注意最后一次落地后虽然要计算弹起的高度,我们还要输出它,但是我们走过的距离已经没有它的,我们此时已经是落地55次了,第n次落地相当于第n-1次弹起

alt

利用C++的cout控制浮点数的输出位数我们要用到iomanip头文件,在输出数据前要加<< setprecision(6)控制输出位数。

#include <iostream>
#include <iomanip>
using namespace std;
 
int main() {
    double h;
    int n = 5;
    cin >> h;
    double dis = 0;
    for(int i = 0; i < n; i++){
        dis += h; //每次加上落下来的距离
        h /= 2; //弹起距离缩短一半
        if(i == n - 1)
            cout << setprecision(6) << dis << endl << setprecision(6) << h << endl;
        dis += h; //弹上去走的距离
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(1)O(1),循环5次,常数时间
  • 空间复杂度:O(1)O(1),无额外空间

方法二:直接计算

具体做法:

因为每次落下后弹起距离都是落下高度的一半,而计算的次数是一定的,只是因为初始高度不同,产生不同的结果,因此我们可以等比例缩放,不同的初始高度和不同的结果之间的比例,其实就是高度为1时的结果,题目示例已经展示出来了,因此最终走过的距离就是2.875height2.875*height,第五次弹起的高度就是0.03125height0.03125*height

alt

#include <iostream>
#include <iomanip>
using namespace std;
 
int main() {
    double h;
    cin >> h;
    cout << setprecision(6) << 2.875 * h << endl << setprecision(6) << 0.03125 * h << endl;
    return 0;
}

复杂度分析:

  • 时间复杂度:O(1)O(1),直接计算,常数时间
  • 空间复杂度:O(1)O(1),无额外空间