信息学奥赛一本通 1085:球弹跳高度的计算 | OpenJudge NOI 1.5 20:球弹跳高度的计算

【题目链接】

ybt 1085:球弹跳高度的计算
OpenJudge NOI 1.5 20:球弹跳高度的计算

【题目考点】

1. 循环

【解题思路】

1. 使用循环描述球的弹跳过程

写法1:以一次弹起后下落为一个周期

设sum表示球经过的总距离,h是下一次弹起的高度
一开始第1次下落,高度h,sum为h。
循环控制变量i表示第几次弹起,每次循环是先弹起后下落,弹起和下落的高度为上次下落的高度h的二分之一,所以h /= 2,每次弹起落下的距离为2h。
第9次弹起后下落,经过的总距离为第10次弹起也就是第10次落地前经过的总距离。下一次第10次弹起时,弹起高度要再次减半,所以弹起高度为h/2。

写法2:以一次下落后弹起为一个周期

设sum表示球经过的总距离,h是这一次下落的高度
循环控制变量i表示第几次下落,每次循环是先下落后弹起,下落高度为h,弹起高度减半,h变为h/2。
第9次下落弹起后,球还需要下落h距离才是第10次落地时球经过的距离。所以总距离为sum+h,第10次弹起时,高度再次减半,为h/2。

2. 数学计算

分析各次落地前弹跳的距离
设球的初始高度是 h h h

  • 第1次下落 h h h,第1次落地,第1次反弹 h 2 \frac{h}{2} 2h
  • 第2次下落 h 2 \frac{h}{2} 2h,第2次落地,第2次反弹 h 4 \frac{h}{4} 4h
  • 第3次下落 h 4 \frac{h}{4} 4h,第3次落地,第3次反弹 h 8 \frac{h}{8} 8h
  • 第i次下落 h 2 i − 1 \frac{h}{2^{i-1}} 2i1h,第i次落地,第i次反弹 h 2 i \frac{h}{2^i} 2ih
    第10次落地之前,共经历了10次下落,9次反弹,将下落和反弹的距离加和,设总距离为s:
    s = h + h 2 + h 2 + h 4 + h 4 + . . . + h 2 9 + h 2 9 = h + 2 ( h 2 + h 4 + . . . + h 2 9 ) = h + h + h 2 + h 4 + . . . + h 2 8 \begin{aligned} s &= h + \frac{h}{2} +\frac{h}{2} + \frac{h}{4}+\frac{h}{4}+...+\frac{h}{2^{9}}+\frac{h}{2^{9}}\\&= h + 2(\frac{h}{2} + \frac{h}{4} + ... +\frac{h}{2^{9}}) \\ &= h + h + \frac{h}{2} + \frac{h}{4} + ... +\frac{h}{2^{8}} \end{aligned} s=h+2h+2h+4h+4h+...+29h+29h=h+2(2h+4h+...+29h)=h+h+2h+4h+...+28h
  • 根据等比序列加和公式:
    S n = a 1 1 − q n 1 − q S_n = a_1\frac{1-q^n}{1-q} Sn=a11q1qn
    可以得到
    s = h ( 1 + 1 + 1 2 + 1 4 + . . . + 1 2 8 ) = h ( 1 + 1 − ( 1 2 ) 9 1 − 1 2 ) = h ( 3 − 1 2 8 ) \begin{aligned} s &= h(1 + 1 + \frac{1}{2} + \frac{1}{4} + ... +\frac{1}{2^{8}}) \\ &=h(1 + \frac{1-(\frac{1}{2})^9}{1-\frac{1}{2}})\\ &= h(3 - \frac{1}{2^8}) \end{aligned} s=h(1+1+21+41+...+281)=h(1+1211(21)9)=h(3281)
  • 根据规律可知,第10次反弹的距离为: h 2 10 \frac{h}{2^{10}} 210h

【题解代码】

解法1:使用循环描述球的运行过程
  • 写法1:以一次弹起后下落为一个周期
#include <bits/stdc++.h>
using namespace std;
int main()
{
    double h, sum;//h:初始高度 sum:球经过的总距离 
    cin >> h;
    sum = h;//sum:总距离初始值设为h,即第一次下落的距离为h
    for(int i = 1; i <= 9; ++i)//i表示第几次弹起 
    {
        h /= 2;//落地后弹跳高度变为原来的一半。运算后h为第i次弹起的高度 
        sum += 2 * h;//球弹起距离h,下落距离h,经过2h距离后再次落地。运行这句后,此时sum表示第i+1次弹起前小球经过的距离 
    }
	cout << sum << endl << h/2 << endl;//此时sum为第10次弹起前也就是第10次落地时经过的距离,h为第10次下落的高度,第10次弹起的高度应该为h/2 
    return 0;
}
  • 写法2:以一次下落后弹起为一个周期
#include <bits/stdc++.h>
using namespace std;
int main()
{
    double h, sum;//h:初始高度 sum:球经过的总距离 
    cin >> h;
    for(int i = 1; i <= 9; ++i)//i表示第几次下落 
    {
    	sum += h;//第i次下落距离h 
        h /= 2;//落地后弹跳高度变为原来的一半。
        sum += h;//球弹起距离h
    }
	cout << sum+h << endl << h/2 << endl;//此时sum为第10次下落前经过的距离,加上h为第10次下落的高度,就是经过的总距离。第10次弹起的高度应该为h/2 
    return 0;
}
解法2:根据数学

推导输出结果
在上述【解题思路】中得到结论:
球弹跳的总距离: h ( 3 − 1 2 8 ) h(3 - \frac{1}{2^8}) h(3281)
第10次弹起的距离: h 2 10 \frac{h}{2^{10}} 210h

#include <bits/stdc++.h>
using namespace std;
int main()
{
    double h;
    cin>>h; 
    cout<<h * (3 - 1 / pow(2, 8))<<endl<<h / pow(2, 10)<<endl;
    return 0;
}
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值