提示:文章
文章目录
前言
前期疑问:
本文目标:
一、背景
最近
二、HJ38 求小球落地5次后所经历的路程和第5次反弹的高度
# 2.1 题目
描述
假设一个球从任意高度自由落下,每次落地后反跳回原高度的一半; 再落下, 求它在第5次落地时,共经历多少米?第5次反弹多高?
数据范围:输入的小球初始高度满足1≤n≤1000 ,且保证是一个整数
输入描述:
输入起始高度,int型
输出描述:
分别输出第5次落地时,共经过多少米以及第5次反弹多高。
注意:你可以认为你输出保留六位或以上小数的结果可以通过此题。
示例1
输入:
1
复制
输出:
2.875
0.03125
2.2 代码
2.2.1 第一版
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
float getLength(int num)
{
float length = 0.0f;
if(num == 1 || num == 2)
{
length = 1;
}
else if(num > 2)
{
length = pow(0.5, num - 2);
}
//printf("%f,%d\n", length, num);
return length;
}
float getTotalLength(int num)
{
float ret = 0.0f;
while(num--)
{
ret += getLength(num);
}
return ret;
}
float getHeight(int num)
{
float ret = 1 * (float)pow(0.5, num);
return ret;
}
int main()
{
int num = 0;
while(scanf("%d", &num) != EOF)
{
float finalHeight = getHeight(num);
float totalLength = getTotalLength(num);
printf("%.6f\n%.6f", totalLength, finalHeight);
}
return 0;
}
上述代码是有问题的。经过调试发现这里写的代码有问题
while(num--)
这边本题中要先算num值为5的情况。本来看这代码,先运算再减减,认为没有错误,其实代码中是从4开始计算的。原因就是
先运算while判断,然后减减为4,参与下面的代码计算了。
代码有问题,修改后发现代码还是隐藏了很大的问题,那就是根本没有理解题目的意思。简直惨烈
题目设计的是当输入高度值后,经过五次弹跳后走过的总路程和第五次弹起高度是多少?
经过大幅修改成下面的代码
2.2.2 第二版
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define BALL_JUMP_TIMES 5
float getLength(int height, int time)
{
float length = 0.0f;
if(time == 1 || time == 2)
{
length = (float)height;
}
else if(time > 2)
{
length = height * pow(0.5, time - 2);
}
return length;
}
float getTotalLength(int num)
{
float ret = 0.0f;
float length = (float)num;
int time = BALL_JUMP_TIMES;
while(time)
{
ret += getLength(num, time);
time--;
}
return ret;
}
float getHeight(int num)
{
float ret = num * (float)pow(0.5, BALL_JUMP_TIMES);
return ret;
}
int main()
{
int num = 0;
while(scanf("%d", &num) != EOF)
{
float finalHeight = getHeight(num);
float totalLength = getTotalLength(num);
printf("%.6f\n%.6f", totalLength, finalHeight);
}
return 0;
}
这一版ac了
2.2.3 思考
我当时在写这代码的时候,就在想是不是要用递归的方法,当时脑子很糊涂,现在写完了再细细琢磨一下,这个题目也是可以用递归的。
现在想了一下好像用递归的方法好像也不是很合适。我回想生兔子的哪个题目,兔子的出生是有规律的,比如兔子第二个月会生出一个兔子,那么经过整理,n个月兔子的总数量应该是
月份 | 1 | 2 | 3 | 4 | 5 | 6 | … |
---|---|---|---|---|---|---|---|
数量 | 1 | 1 | 2 | 3 | 5 | 8 | … |
所以数量是有规律的。说的更明白就是第n个月的数量和第n-1和第n-2个月的数量是有关系的。
所以基于上述的数据,可以写出递归的代码
#include <stdio.h>
#include <stdlib.h>
int getToatalData(int month)
{
int num = 0;
if(month == 1 || month == 2)
{
num = 1;
}
else if(month > 2)
{
num = getToatalData(month - 1) + getToatalData(month - 2);
}
return num;
}
//demo
int main()
{
int month = 0;
while(scanf("%d", &month) != EOF)
{
int num = getToatalData(month);
printf("%d\n", num);
}
return 0;
}
上面就是可以正常应用递归方法的案列和代码
三、
3.1
总结
未完待续