自学内容网 自学内容网

【C++】球弹跳高度的计算:思路分析与优化


在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++


在这里插入图片描述


💯前言

  • 在学习C++编程的过程中,实践题目往往是提高编程思维和熟悉语法的有效方法。本次我们讨论了一道关于球弹跳高度和总路程的计算题目,分析了题目要求以及两种不同的解法。通过对比代码设计和逻辑实现,我们总结出优化方法,并进一步拓展相关编程知识。本文将以完整的结构带领读者梳理这道题目的思路、实现和优化方向。
    C++ 参考手册
    在这里插入图片描述

💯题目描述

B2076 球弹跳高度的计算
在这里插入图片描述

题目要求如下:

一球从一定高度(整数,高度单位为米)自由下落,每次落地后反弹回原高度的一半。经过 10 次落地后,计算:

  1. 球在第 10 次落地时,共经过多少米的总路程?
  2. 第 10 次反弹的高度是多少?

输入格式

输入一个整数:表示球的初始高度。

输出格式

输出包含两行:

  1. 第 10 次落地时,共经过的米数(保留小数)。
  2. 第 10 次反弹的高度(保留小数)。

输入输出示例

输入:

20

输出:

59.9219
0.0195313

💯两种代码实现及其对比

在本次学习中,我们首先通过学生的代码完成了对题目逻辑的实现。随后,又参考了老师的代码。两种解法都满足了题目需求,但在变量使用、循环设计等细节上有所差异。下面,我们分别分析两种代码的逻辑,并总结其优缺点。

我的代码实现

以下是我的代码实现:

#include <iostream>
using namespace std;

int main() {
    int h;
    cin >> h; // 输入初始高度

    double s = h, h2 = h * 1.0 / 2; // 初始化总路程和第一次反弹高度
    int i = 0; // 循环计数器

    do {
        s += h2 * 2; // 每次反弹产生的路程
        h2 /= 2; // 反弹高度减半
        i++; // 计数器递增
    } while (i < 9); // 循环 9 次(第 1 次下落已单独处理)

    cout << s << endl; // 输出总路程
    cout << h2 << endl; // 输出第 10 次反弹高度
    return 0;
}

在这里插入图片描述

代码分析

  1. 变量定义:

    • h:表示球的初始高度,输入后赋值给变量。
    • s:记录总路程,初始值为第一次下落的高度。
    • h2:记录当前反弹高度,初始值为第一次反弹高度,即 h / 2
  2. 逻辑结构:

    • 使用 do-while 循环,确保至少执行一次循环。
    • 在每次循环中:
      • 累加当前反弹的路程 h2 * 2(下落一次、反弹一次)。
      • 更新 h2 为下一次反弹高度(减半)。
    • 循环 9 次,配合初始的第 1 次下落,共计 10 次。
  3. 输出:

    • 总路程保存在 s 中。
    • 第 10 次反弹的高度保存在 h2 中。

优点与不足

  • 优点:

    • 程序逻辑清晰,分步骤计算。
    • 使用浮点类型 double,能够处理小数精度问题。
  • 不足:

    • 使用了额外变量 h2,略显冗余。
    • do-while 循环的计数逻辑不够直观(计数从 0 开始,循环 9 次)。
    • 缺乏对输出精度的控制。

老师的代码实现

以下是老师提供的代码实现:

#include <iostream>
using namespace std;

int main() {
    double h = 0; // 初始化 h 为 0,接收输入的高度
    cin >> h;

    int i = 1; // 循环计数器,从第 1 次开始
    double total = h; // 总路程,先加上第一次下落的高度

    do {
        h /= 2;        // 反弹高度减半
        total += h * 2; // 加上反弹两次的路程
        i++;            // 次数 +1
    } while (i <= 9);    // 循环到第 9 次为止(共 10 次落地)

    cout << total << endl; // 输出总路程
    cout << h / 2 << endl; // 输出第 10 次反弹高度
    return 0;
}

在这里插入图片描述

代码分析

  1. 变量定义:

    • h:表示当前高度,初始为输入高度。
    • total:记录总路程,初始为第一次下落的高度。
  2. 逻辑结构:

    • 使用 do-while 循环计算剩余的 9 次落地。
    • 每次循环:
      • 高度减半。
      • 累加当前反弹的路程 h * 2
    • 循环计数从 1 开始,直到第 9 次。
  3. 输出:

    • 第 10 次反弹高度直接通过 h / 2 计算,无需额外变量。

优点与不足

  • 优点:

    • 变量定义更简洁,直接使用 h 表示当前高度。
    • 计数逻辑更符合人类直觉(从 1 开始计数)。
    • 避免了不必要的变量。
  • 不足:

    • 缺少对输出精度的设置。

💯两种实现的对比总结

比较维度我的代码老师的代码
变量使用使用额外变量 h2 表示反弹高度直接复用 h 表示当前高度
计数逻辑从 0 开始计数,循环 9 次从 1 开始计数,循环 9 次
输出精度未控制输出精度未控制输出精度
代码简洁性变量定义较多,逻辑稍显冗余变量少,逻辑更清晰

💯优化与拓展

结合两种实现的优点,可以进一步优化代码:

优化后的代码

#include <iostream>
#include <iomanip> // 引入格式化输出库
using namespace std;

int main() {
    double h;            // 球的初始高度
    cin >> h;

    double total = h;    // 总路程,先加上第一次落地的高度
    int i = 1;           // 计数器,从第 1 次开始

    do {
        h /= 2;          // 当前反弹高度为上一高度的一半
        total += h * 2;  // 累加上下两次路程
        i++;             // 次数 +1
    } while (i <= 9);    // 循环至第 9 次结束

    // 设置输出精度
    cout << fixed << setprecision(6);
    cout << total << endl;  // 总路程
    cout << h / 2 << endl;  // 第 10 次反弹高度
    return 0;
}

在这里插入图片描述
在这里插入图片描述

优化点

  1. 使用 fixedsetprecision 控制输出精度,保证小数点后一致位数。
  2. 避免了冗余变量,直接使用 h 表示当前高度。
  3. 计数逻辑更直观,从 1 开始计数。

💯小结

  • 在这里插入图片描述
    本次讨论中,我们通过一道关于球弹跳高度的计算题目,探讨了如何用 C++ 编程实现数学逻辑。通过分析和优化,我们发现:
  1. 代码的简洁性和可读性很重要: 减少冗余变量、优化计数逻辑能让代码更清晰。
  2. 输出精度控制: 使用 setprecision 是处理小数输出的重要技巧。
  3. 逻辑设计与数学结合: 通过循环和递归更新变量,实现题目中数学模型的计算。

在这里插入图片描述


学习C++是一段既充满挑战又令人收获颇丰的旅程。作为一门历史悠久且广泛应用的编程语言,C++不仅提供了强大的功能,还以其复杂性闻名。因此,在学习这门语言的过程中,我深刻体会到了它的深度和广度,同时也总结了一些心得,希望对未来的学习者有所帮助。

初识C++:从基础开始

在接触C++之前,我对编程的了解仅限于一些基础的概念,例如变量、循环和条件语句。C++的学习从这些最基本的部分开始,帮助我夯实了编程的基础。C++的语法严格,这在一开始可能会让人感到不适应,但也正是因为这种严格性,它迫使我养成了良好的编程习惯。例如,必须明确变量的类型,让我更注重程序的逻辑性和可读性。

掌握面向对象编程思想

C++最具特色的部分之一就是面向对象编程(OOP)。初次接触类和对象时,我对这种编程范式感到新奇而又困惑。OOP的核心思想是将现实世界中的事物抽象为类,通过类的实例化生成对象,从而以更直观的方式管理程序的复杂性。

我记得刚开始学习类时,写了一个关于"学生管理系统"的小程序。通过定义"学生"类,设置姓名、学号和成绩等属性,再为类添加一些方法,如打印信息和计算平均分,我逐渐理解了OOP的实际应用价值。这种封装、继承和多态的思想让我感受到C++的强大,也让我认识到软件设计中的灵活性。

理解指针与内存管理

如果说C++中有什么让我印象最深刻且花费最多时间去理解的内容,那一定是指针和内存管理。指针是C++的一大特色,同时也是许多初学者的难点。我在学习过程中经常因为指针的误用导致程序崩溃,甚至遇到一些难以调试的问题。

为了更好地理解指针,我专门阅读了一些资料,并亲手编写了许多练习程序。例如,我通过编写动态数组、链表和二叉树等数据结构,深刻体会到了指针在动态内存分配中的重要性。通过这些实践,我不仅掌握了指针的使用,还学会了如何使用newdelete进行内存管理,以及如何避免内存泄漏。

学习STL的便利性

C++的标准模板库(STL)是学习过程中的一个亮点。STL提供了许多现成的数据结构和算法,例如向量(vector)、队列(queue)、栈(stack)以及哈希表(unordered_map)等。在学习STL之前,我花了大量时间自己实现这些数据结构,而STL的出现大大简化了我的开发过程。

通过学习STL,我认识到了高效代码的重要性,也学会了如何快速解决问题。例如,在一次编程竞赛中,我需要快速实现一个排序功能,而STL中的sort函数帮助我节省了大量时间。与此同时,我还了解了STL背后的一些实现原理,例如迭代器的使用和时间复杂度的分析。

错误与调试:不可避免的成长

在学习C++的过程中,错误和调试是不可避免的。无论是编译错误还是运行时错误,几乎每次编写代码时都要面对各种各样的问题。这让我一开始感到沮丧,但随着经验的积累,我学会了如何分析错误信息并快速定位问题。

调试工具是我的好帮手。例如,使用gdb调试器让我能够逐行检查代码的执行过程,而现代的集成开发环境(IDE)如Visual Studio则提供了更直观的调试界面。此外,我还养成了在代码中添加日志和断点的习惯,这些技巧帮助我在处理复杂问题时更加得心应手。

提升编程效率的技巧

随着对C++的深入学习,我也总结了一些提升编程效率的技巧:

  1. 模块化编程:将代码分成多个文件,使得每个模块专注于完成特定的任务,从而提高代码的可读性和可维护性。
  2. 注重代码规范:遵循一致的命名规则和缩进风格,让代码更易于理解。
  3. 利用C++11/14/17的新特性:例如,auto关键字简化了变量类型的声明,智能指针(std::shared_ptrstd::unique_ptr)帮助更安全地管理内存。
  4. 多阅读优秀代码:通过阅读开源项目中的代码,我学到了很多实用的编程技巧和设计模式。

总结与展望

学习C++不仅让我掌握了一门编程语言,更让我养成了严谨的思维方式。在这个过程中,我学会了如何从问题中总结经验,如何不断优化自己的代码,以及如何以更高效的方式解决实际问题。

未来,我希望能够继续深入学习C++的高级特性,例如模板编程和多线程开发,同时也希望能够将C++应用于更多实际项目中,如游戏开发、嵌入式系统和高性能计算。我相信,通过不断的实践和学习,我将在C++的世界中发现更多的乐趣和可能性。

总之,C++是一门值得花时间深入学习的语言。尽管它的学习曲线较陡,但正是这种挑战让我更加热爱编程,也让我在每次克服困难后获得了巨大的成就感。



原文地址:https://blog.csdn.net/2201_75539691/article/details/144797199

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!