今天来写一道小球落地题‘ - ’
题目如下:
        小球从某一高度落下,每次落地后反跳回原来高度的一半,再落下。
输入弹球的初始高度 M 和回弹次数 N, 输出弹球第 N 次回弹后的高度 和达到该高度后所经过的距离(保留两位小数)
(0<M<2000, 0<N<50)
样例输入:
       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呢,好难猜啊?我一开始写的有啊,往上翻翻
好了,有关这一题的分享就到这里了,再见了