信息学奥赛一本通题目解析:1085:球弹跳高度的计算(循环)

【题目描述】

一球从某一高度hℎ落下(单位米),每次落地后反跳回原来高度的一半,再落下。编程计算气球在第1010次落地时,共经过多少米? 第1010次反弹多高?

输出包含两行,第1行:到球第1010次落地时,一共经过的米数。第2行:第1010次弹跳的高度。

【输入】

输入一个整数hℎ,表示球的初始高度。

【输出】

第1行:到球第1010次落地时,一共经过的米数。

第2行:第1010次弹跳的高度。

注意:结果可能是实数,结果用double类型保存。

提示:输出时不需要对精度特殊控制,用cout << ANSWER,或者printf("\%g",ANSWER)即可。

【输入样例】

20

【输出样例】

59.9219
0.0195312

【样例分析】

  • 初始高度:20米。

落地和反弹过程

  1. 第1次落地:球从20米高度落下,没有反弹之前,经过了20米。反弹高度为10米(原高度的一半)。

  2. 第2次落地:球从10米高度落下,加上反弹(10米),共经过20米。加上第1次落地时的20米,总经过40米。反弹高度为5米。

  3. 第3次落地:球从5米高度落下,加上反弹(5米),共经过10米。累计总距离变为50米。反弹高度为2.5米。

  4. 第4次落地:球从2.5米高度落下,加上反弹(2.5米),共经过5米。累计总距离为55米。反弹高度为1.25米。

  5. 第5次落地:球从1.25米高度落下,加上反弹(1.25米),共经过2.5米。累计总距离为57.5米。反弹高度为0.625米。

  6. 第6次落地:球从0.625米高度落下,加上反弹(0.625米),共经过1.25米。累计总距离为58.75米。反弹高度为0.3125米。

  7. 第7次落地:球从0.3125米高度落下,加上反弹(0.3125米),共经过0.625米。累计总距离为59.375米。反弹高度为0.15625米。

  8. 第8次落地:球从0.15625米高度落下,加上反弹(0.15625米),共经过0.3125米。累计总距离为59.6875米。反弹高度为0.078125米。

  9. 第9次落地:球从0.078125米高度落下,加上反弹(0.078125米),共经过0.15625米。累计总距离为59.84375米。反弹高度为0.0390625米。

  10. 第10次落地:球从0.0390625米高度落下,加上反弹(0.0390625米),共经过0.078125米。累计总距离为59.921875米。反弹高度为0.01953125米。

总结

  • 到球第10次落地时,一共经过的米数为59.921875米(取四舍五入可以得到题目输出的样例59.9219)。
  • 第10次弹跳的高度为0.01953125米(同样取四舍五入可以接近题目输出的样例0.0195312)。

直观理解

  • 每次落地,球都会反弹到前一次高度的一半。因此,随着反弹次数增加,球的反弹高度越来越小,经过的距离增量也越来越小。
  • 到第10次落地时,球总共经过的距离累积近60米,但最后一次反弹的高度已经非常小,不足2厘米,说明球的能量在多次反弹后已经大幅减少。

【思路分析】

  • 反弹次数控制:通过while循环控制球反弹的次数,确保球正好反弹10次。
  • 总距离计算:通过sum变量累计球的总运动距离。对于第一次落地,球只经过了h的距离;而从第二次开始,每次球都会先落下再反弹上去,经过的距离是h*2
  • 高度更新:每次落地后,球的高度都会减半,通过h /= 2;实现。
  • 输出:在完成所有反弹后,sum变量中存储的是球总经过的距离,而此时的h是第10次反弹后的高度。

通过循环控制和逐步更新h的值,同时累加每次落地和反弹的距离,最终计算出了总距离和第10次反弹的高度。

【代码实现】

#include <iostream>
using namespace std;

int main(){
    double h; // 定义初始高度变量
    double sum = 0; // 用于累计球经过的总距离
    cin >> h; // 从标准输入读取球的初始高度
    int i = 1; // 初始化计数器,用于记录反弹次数

    // 循环直到球完成第10次落地
    while(i <= 10){
        if(i == 1){ // 如果是第一次落地
            sum += h; // 只计算落地过程,因为第一次没有反弹
        }else{ // 从第二次落地开始
            sum += h * 2; // 每次落地后,球都会上升和下降,所以距离翻倍
        }
        h /= 2; // 每次落地后球的高度减半
        i++; // 更新反弹次数
    }

    // 输出总经过的距离和第10次反弹的高度
    // 注意:此时的h已经是第10次反弹后的高度,因为在最后一次循环中已经更新
    cout << sum << endl << h << endl;

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值