今天来写一道小球落地题‘ - ’
题目如下:
小球从某一高度落下,每次落地后反跳回原来高度的一半,再落下。
输入弹球的初始高度 M 和回弹次数 N, 输出弹球第 N 次回弹后的高度 和达到该高度后所经过的距离(保留两位小数)
(0<M<2000, 0<N<50)
样例输入:
1000 5
样例输出
31.25
2906.25怎么说,因为一开始小球每次落地后反跳回原来高度的一半,再落下。自己没有注意到“再落下”,所以定义的'h'(小球之后的高度,开始高度是M,写int h = M,为了之后好计算)没乘以2,小球要回到地面上,你不能让它悬在空中吧。牛顿听了都炸了
1000 5
样例输出
31.25
2906.25怎么说,因为一开始小球每次落地后反跳回原来高度的一半,再落下。自己没有注意到“再落下”,所以定义的'h'(小球之后的高度,开始高度是M,写int h = M,为了之后好计算)没乘以2,小球要回到地面上,你不能让它悬在空中吧。牛顿听了都炸了
但是我想的是再定义个数组double a[2],避免了函数返回值 (return)只能返回一个值的情况。
先看下一下,一开始的写法:

#include<iostream> using namespace std; double leng(double M,int N,double a[2]); int main(){ double M;int N; cin>>M>>N; double a[2]; leng(M,N,a); cout<<a[0]<<endl; cout<<a[1]<<endl; return 0; } double leng(double M,int N,double a[2]){ int h = M; int count = 1; M /= 2.0; count += 1; if(N==1){ a[0] = h/2.0; a[1] = h + h/2.0; return 0; } else if(N>0){ a[0] = M; a[1] = M + h; } else return 0; }很明显,对于 N>1 的情况,自己的计算逻辑不完整,没有考虑多次反弹的累积距离(大头😒)。而且你看函数返回类型是 double,却没有返回任何有意义的值(最后只是返回 0)6!。
int count = 1;你要干嘛?回弹次数 N 有啊!删掉,要的是定义一个输入距离的double distance变量!
所以我应该去使用循环正确计算每次反弹后的高度和总距离。要注意(距离计算逻辑:第一次只有下落距离,之后每次反弹都要加上升和下落距离(除了最后一次反弹只加下落距离))。嗯!嗯?:
#include<iostream> #include<stdio.h> using namespace std; void leng(double M,int N,double a[2]); int main(){ double M; int N; cin>>M>>N; double a[2]; leng(M,N,a); printf("%.2lf\n",a[0]); printf("%.2lf",a[1]); return 0; } void leng(double M,int N,double a[2]){ double height = M; double distance = 0; distance += height; // 第一次下落 int i; for(i=1;i<=N;i++){ height /= 2.0; if(i != N){ // 反弹后上升的距离,最后一次反弹后不需要再加上升距离 distance += 2*height; }else{ distance += height; // 最后一次只加下落距离 } } a[0] = height; a[1] = distance; }
distance += height; // 第一次下落这步很重要,不加开始高度都没加,比如样例输入的: 1000,不加最后结果为1906.25,发现不对劲了吧🤣
因为要小数后两位所以我用的c语言写法:
#include<stdio.h>这是c标准的头文件,外加输出写法,c++可以兼容的:
printf("%.2lf\n",a[0]); printf("%.2lf",a[1]);你要写C++写法也行

cout << fixed << setprecision(2) << a[0] << endl; cout << fixed << setprecision(2) << a[1] << endl;我将函数改为 void 类型,因为它通过数组参数返回结果void leng()。而不是用double leng();
可以看到案例的详细运行过程:
初始高度:1000:
第一次反弹高度:500,总距离:1000 + 500*2 = 2000
第二次反弹高度:250,总距离:2000 + 250*2 = 2500
第三次反弹高度:125,总距离:2500 + 125*2 = 2750
第四次反弹高度:62.5,总距离:2750 + 62.5*2 = 2875
第五次反弹高度:31.25,总距离:2875 + 31.25 = 2906.25
嗯,为什么要乘以2呢,好难猜啊?我一开始写的有啊,往上翻翻
。
好了,有关这一题的分享就到这里了,再见了
!
