今天来写一道小球落地题‘ - ’
题目如下:
小球从某一高度落下,每次落地后反跳回原来高度的一半,再落下。
输入弹球的初始高度 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呢,好难猜啊?我一开始写的有啊,往上翻翻
。
好了,有关这一题的分享就到这里了,再见了
!
!
京公网安备 11010502036488号