题目的主要信息:

  • 有一个小球从高度h下落,碰到地板会反弹,反弹高度为下落高度的一半
  • 求解第五次落地所经历的路程和第五次反弹的高度

方法一:模拟下落

首先我们来看小球从h高度下落的过程: alt 用height_5记录每次弹起的高度,height_total记录总路程,用一个for循环模拟弹起又落地的过程,每次的反弹结束后反弹高度height_5都变为原来的一半,经历的路程height_total需要加上两个反弹高度。由于第五次落地的时候只经历四次反弹,因此for只需要四次就可以计算第五次落地的时候小球经历的路程,最后我们还要输出第五次反弹的高度,即第四次反弹高度除以2。

具体做法:

#include<iostream>

using namespace std;

int main(){
    double height;
    while(cin>>height){//可能有多个输入
        double height_5=height;//height_5记录每次反弹的高度
        double height_total=height;//保存总经历多少米
        for(int i=1;i<5;i++){//因为总经历多少米是到第五次落地为止,即第四个反弹落地
            height_5=height_5/2;//反弹高度
            height_total+=height_5*2;//每反弹一次就经历两个反弹高度
        }
        cout<<height_total<<endl<<height_5/2<<endl;//需要计算第五次反弹的高度
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(1)O(1),循环只要4次,是常数时间。
  • 空间复杂度:O(1)O(1),只用了常数空间。

方法二:归纳计算

整个下落过程为: alt 根据这个过程我们可以直接得到落地五次所经历的路程sum=height+(height/2)2+(height/4)2+(height/8)2+(height/16)2sum=height+(height/2)*2+(height/4)*2+(height/8)*2+(height/16)*2,第五次反弹的高度为height/32。

具体做法:

#include<iostream>

using namespace std;

int main(){
    double height;
    while(cin>>height){
        double sum=height+(height/2)*2+(height/4)*2+(height/8)*2+(height/16)*2;
        cout<<sum<<endl<<height/32<<endl;
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(1)O(1),由于直接计算,只需要常数时间。
  • 空间复杂度:O(1)O(1),只需要常数空间。