【C++】B2064 斐波那契数列


在这里插入图片描述

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

文章目录

  • 💯前言
  • 💯题目描述
    • 输入格式
    • 输出格式
    • 输入输出样例
      • 输入
      • 输出
  • 💯思路分析
    • **题目本质**
  • 💯代码实现与对比
    • **我的代码实现**
      • 代码展示
      • 思路解析
      • 优点
      • 不足
    • **老师的代码实现**
      • 代码展示
      • 思路解析
      • 优点
      • 不足
  • 💯优化方法
    • **优化方案:查表法**
      • 优化代码
      • 优化分析
  • 💯扩展与总结
    • **斐波那契数列的优化方法**
  • 💯 **小结**


在这里插入图片描述


💯前言

  • 斐波那契数列问题是算法学习中的经典例题。通过这一类问题,不仅可以巩固对递推关系和循环的理解,还能学习到如何通过预处理和查表优化代码效率。本次文章将通过一道具体的题目,从题目分析、代码实现、优化思路以及扩展应用四个部分,全面解析斐波那契数列问题的解决方法。
    C++ 参考手册
    在这里插入图片描述


💯题目描述

B2064 斐波那契数列
在这里插入图片描述

题目要求是计算斐波那契数列的第 a a a 项。数列的定义如下:

  • 第一项和第二项均为 1:
    F ( 1 ) = 1 , F ( 2 ) = 1 F(1) = 1, \quad F(2) = 1 F(1)=1,F(2)=1
  • n n n 项满足递推关系:
    F ( n ) = F ( n − 1 ) + F ( n − 2 ) (n ≥ 3) F(n) = F(n-1) + F(n-2) \quad \text{(n ≥ 3)} F(n)=F(n1)+F(n2)(n ≥ 3)

题目的输入输出格式如下:

输入格式

  • 第 1 行:测试数据的组数 n n n
  • 接下来 n n n 行,每行包含一个正整数 a a a,表示要求出斐波那契数列的第 a a a 项( 1 ≤ a ≤ 30 1 \leq a \leq 30 1a30)。

输出格式

  • 输出 n n n 行,每行对应一个输入 a a a 的结果。

输入输出样例

输入

4
5
10
30
1

输出

5
55
832040
1

💯思路分析

题目本质

斐波那契数列是一个经典的递推问题,通过递推公式 F ( n ) = F ( n − 1 ) + F ( n − 2 ) F(n) = F(n-1) + F(n-2) F(n)=F(n1)+F(n2) 可以不断计算出后续的项。对于这一问题,我们需要重点解决以下几点:

  1. 如何高效计算第 a a a 项?

    • 如果直接计算每个 a a a,复杂度较高,尤其是当 n n n a a a 较大时,会有很多重复计算。
    • 如果提前计算好数列的所有值,后续直接查表,则可以显著优化。
  2. 如何处理边界情况?

    • a = 1 a = 1 a=1 a = 2 a = 2 a=2 时,不需要递推,直接输出 1。
  3. 代码的简洁性与可读性

    • 变量的命名是否语义化,代码逻辑是否清晰。

💯代码实现与对比

以下我们对两种代码方案进行分析,一个是学生(你)的代码实现,另一个是老师提供的参考实现。

我的代码实现

代码展示

#include <iostream>
using namespace std;

int main() {
    int n;  // 测试数据组数
    cin >> n;

    while (n--) {  // 循环处理每组测试数据
        int a;
        cin >> a;

        // 边界情况
        if (a == 1 || a == 2) {
            cout << 1 << endl;
            continue;  // 直接输出后处理下一组测试数据
        }

        // 使用循环计算第 a 项
        int prev1 = 1, prev2 = 1;  // 前两项的值
        int current;  // 当前项的值
        for (int i = 3; i <= a; ++i) {  // 从第3项开始递推
            current = prev1 + prev2;  // 当前项等于前两项之和
            prev1 = prev2;  // 更新前两项的值
            prev2 = current;
        }

        cout << current << endl;  // 输出结果
    }

    return 0;
}

在这里插入图片描述

思路解析

  1. 边界条件处理
    • a = 1 a = 1 a=1 a = 2 a = 2 a=2 时,直接输出结果 1,无需循环计算。
  2. 递推计算
    • F ( 3 ) F(3) F(3) 开始循环,通过变量 prev1prev2 保存前两项的值,计算当前项。
  3. 变量使用
    • prev1prev2 分别保存前两项,current 保存当前项。

优点

  • 代码逻辑清晰,结构化程度高,适合扩展。
  • 边界情况单独处理,减少不必要的计算。

不足

  • 对每个输入 a a a 都需要从头计算,重复计算较多,效率不高。
  • 存在可以进一步优化的空间,例如使用查表法。

老师的代码实现

代码展示

#include <iostream>
using namespace std;

int main() {
    int n = 0;
    int a = 0;
    cin >> n;

    while (n--) {
        cin >> a;

        // 计算第 a 个斐波那契数
        int x = 1;
        int y = 1;
        int z = 1;
        while (a > 2) {
            z = x + y;
            x = y;
            y = z;
            a--;
        }

        cout << z << endl;
    }

    return 0;
}

在这里插入图片描述

思路解析

  1. 变量初始化
    • 定义了 x, y, 和 z 三个变量,分别表示前两项和当前项的值,初始值均为 1。
  2. 递推逻辑
    • 通过 while 循环,当 a > 2 a > 2 a>2 时,不断更新 xyz 的值。
    • 每次循环结束后,z 表示当前的第 a a a 项。
  3. 边界条件
    • 初始值的设置(均为 1)使得当 a = 1 a = 1 a=1 a = 2 a = 2 a=2 时,无需特殊处理。

优点

  • 代码紧凑简洁,没有显式的边界条件分支。
  • 循环逻辑简单直观。

不足

  • 和你的代码一样,没有解决重复计算的问题。
  • while 循环的使用虽然简化了逻辑,但对于大范围递推不如 for 循环明确。

💯优化方法

对于这类小范围的斐波那契问题,可以通过 查表法 显著优化计算效率。

优化方案:查表法

由于题目中 a a a 的范围固定( 1 ≤ a ≤ 30 1 \leq a \leq 30 1a30),我们可以提前计算好斐波那契数列的前 30 项,存入数组中。这样对于每个输入 a a a,只需直接查表输出即可。

优化代码

#include <iostream>
using namespace std;

int main() {
    // 预处理:计算斐波那契数列的前30项
    int fib[31];
    fib[1] = 1;
    fib[2] = 1;
    for (int i = 3; i <= 30; ++i) {
        fib[i] = fib[i - 1] + fib[i - 2];
    }

    int n;
    cin >> n;  // 输入测试组数

    while (n--) {
        int a;
        cin >> a;
        cout << fib[a] << endl;  // 查表输出
    }

    return 0;
}

在这里插入图片描述

优化分析

  1. 时间复杂度

    • 预处理:计算前 30 项的复杂度为 O ( 30 ) O(30) O(30)
    • 查询:每个输入直接查表,复杂度为 O ( 1 ) O(1) O(1)
    • 总复杂度为 O ( 30 + n ) O(30 + n) O(30+n),相较于直接递推的 O ( n ⋅ a max ) O(n \cdot a_{\text{max}}) O(namax) 大大降低。
  2. 空间复杂度

    • 需要额外的数组存储 30 项结果,但空间开销可以忽略不计。
  3. 优点

    • 避免了重复计算,运行效率显著提升。
    • 代码结构更简洁,易于维护。

💯扩展与总结

斐波那契数列的优化方法

  1. 矩阵快速幂

    • 斐波那契数列的递推可以转化为矩阵乘法,通过矩阵快速幂将时间复杂度降为 O ( log ⁡ n ) O(\log n) O(logn)
  2. 递归优化

    • 使用记忆化递归(Memoization)缓存中间结果,避免重复计算。

💯 小结

  • 题目解析:通过递推关系,明确了斐波那契数列的本质和边界条件。
  • 代码实现:比较了两种代码方案,分别分析了它们的优缺点。
  • 优化方法:通过查表法优化,解决了重复计算的问题,提高了效率。
  • 扩展思路:探讨了更高效的算法实现方式。

通过本次题目的解析,相信读者对斐波那契数列的计算和优化有了更深入的理解。在实际问题中,选择合适的算法与优化方法,能够显著提升代码的性能与可维护性。


在这里插入图片描述


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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/945662.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot521基于Spring Boot的校园闲置物品交易系统(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装校园闲置物品交易系统软件来发挥其高效地信息处理的作用&am…

el-table动态行和列及多级表头

主页面 <template><div class"result-wrapper"><dynamic-table :table-data"tableData" :table-header"tableConfig" :tableTitle"tableTitle" :flowParams"flowParams"></dynamic-table></div…

【MySQL】数据库 Navicat 可视化工具与 MySQL 命令行基本操作

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

2024年12月30日Github流行趋势

项目名称&#xff1a;free-programming-books 项目地址url&#xff1a;https://github.com/EbookFoundation/free-programming-books项目语言&#xff1a;HTML历史star数&#xff1a;343,398今日star数&#xff1a;246项目维护者&#xff1a;vhf, eshellman, davorpa, MHM5000,…

Mysql数据库Redo日志和Undo日志的理解

数据库redo日志和undo日志 1、redo日志1.1 redo日志的作用1.1.1 不使用redo日志的问题1.1.2 使用redo日志的好处 1.2 redo日志刷盘策略 2、undo日志2.1 undo日志的作用2.2 undo日志的简要生成过程 1、redo日志 事务的4大特性&#xff08;ACID&#xff09;&#xff1a;原子性、…

Windows配置cuda,并安装配置Pytorch-GPU版本

文章目录 1. CUDA Toolkit安装2. 安装cuDNN3. 添加环境变量配置Pytorch GPU版本 博主的电脑是Windows11&#xff0c;在安装cuda之前&#xff0c;请先查看pytorch支持的版本&#xff0c;cuda可以向下兼容&#xff0c;但是pytorch不行&#xff0c;请先进入&#xff1a;https://py…

Oracle 数据库 dmp文件从高版本导入低版本的问题处理

当前有个需求是将oracle 19c上的数据备份恢复到oracle 11g上使用。我们通过exp命令远程进行备份&#xff0c;然后通过imp进行恢复时出现IMP-00010: not a valid export file, header failed verification报错。 这是数据库版本问题&#xff0c;在使用exp命令导出的时候使用的客…

RedisDesktopManager新版本不再支持SSH连接远程redis后

背景 RedisDesktopManager(又名RDM)是一个用于Windows、Linux和MacOS的快速开源Redis数据库管理应用程序。这几天从新下载RedisDesktopManager最新版本&#xff0c;结果发现新版本开始不支持SSH连接远程redis了。 解决方案 第一种 根据网上有效的信息&#xff0c;可以回退版…

C# 读取多种CAN报文文件转换成统一格式数据,工具类:CanMsgRead

因为经常有读取CAN报文trace文件的需求&#xff0c;而且因为CAN卡不同、记录软件不同会导致CAN报文trace文件的格式都有差异。为了方便自己后续开发&#xff0c;我写了一个CanMsgRead工具类&#xff0c;只要提供CAN报文路径和CAN报文格式的选项即可将文件迅速读取转换为统一的C…

REDIS2.0

string list hash set 无序集合 声明一个key&#xff0c;键里面的值是元素&#xff0c;元素的类型是string 元素的值是唯一的&#xff0c;不能重复 多个集合类型之间可以进行并集&#xff0c;交集&#xff0c;集查的运算 sadd test1 a b c c d &#xff1a;添加5个元素&am…

【源码 导入教程 文档 讲解】基于springboot校园新闻管理系统源码和论文

可做计算机毕业设计JAVA、PHP、爬虫、APP、小程序、C#、C、python、数据可视化、大数据、文案 传统信息的管理大部分依赖于管理人员的手工登记与管理&#xff0c;然而&#xff0c;随着近些年信息技术的迅猛发展&#xff0c;让许多比较老套的信息管理模式进行了更新迭代&#xf…

分布式项目___某污水处理项目

一.分布式项目___污水处理项目 项目地址:https://gitee.com/yanyigege/collaborative-water-springboot.git ​ 1.项目背景 总公司在全国各地有处理污水的项目部,各项目部处理自己的污水,总部需要监控各地分项目部每天处理污水的原料用量,掌握各分部的污水处理情况 ​ 2.功…

小程序基础 —— 08 文件和目录结构

文件和目录结构 一个完整的小程序项目由两部分组成&#xff1a;主体文件、页面文件&#xff1a; 主体文件&#xff1a;全局文件&#xff0c;能够作用于整个小程序&#xff0c;影响小程序的每个页面&#xff0c;主体文件必须放到项目的根目录下&#xff1b; 主体文件由三部分组…

计算机网络 (7)物理层下面的传输媒体

一、定义与位置 物理层是计算机网络体系结构的最低层&#xff0c;它位于传输媒体&#xff08;传输介质&#xff09;之上&#xff0c;主要作用是为数据链路层提供一个原始比特流的物理连接。这里的“比特流”是指数据以一个个0或1的二进制代码形式表示。物理层并不是特指某种传输…

基于FPGA的2ASK+帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可设置SNR

目录 1.算法仿真效果 2.算法涉及理论知识概要 2.1 2ASK调制解调 2.2 帧同步 3.Verilog核心程序 4.完整算法代码文件获得 1.算法仿真效果 vivado2019.2仿真结果如下&#xff08;完整代码运行后无水印&#xff09;&#xff1a; 设置SNR8db 设置SNR20db 整体波形效果&…

各种 Amazon EBS 卷类型

Amazon Elastic Block Store&#xff08;EBS&#xff09;是 Amazon Web Services&#xff08;AWS&#xff09;提供的一项持久性块存储服务&#xff0c;它允许用户为 EC2 实例提供高效、可靠的存储。EBS 卷是 AWS 云环境中存储数据的基础组件&#xff0c;广泛应用于数据库、文件…

nvidia_gpu_exporter 显卡监控

导入 grafana/dashboard.json https://github.com/utkuozdemir/nvidia_gpu_exporter/blob/master/grafana/dashboard.json参考 nvidia_gpu_exporter

jvm排查问题-实践追踪问题 与思路--堆内堆外内存泄漏排查方针

概述 排查问题的一般思路是:现象 ——> 直接原因 ——>根本原因。 从问题现象出发,可以分为 应用逻辑问题、资源使用问题、虚拟机异常: 应用逻辑可能导致报错增加、死锁、程序退出等;资源问题主要集中在CPU上升和内存上升(OOM Kill);虚拟机问题通常包括GC问题、进…

CPT203 Software Engineering 软件工程 Pt.1 概论和软件过程(中英双语)

文章目录 1.Introduction1.1 What software engineering is and why it is important&#xff08;什么是软件工程&#xff0c;为什么它很重要&#xff09;1.1 We can’t run the modern world without software&#xff08;我们的世界离不开软件&#xff09;1.1.1 What is Soft…

【Java数据结构】LinkedList与链表

认识LinkedList LinkedList就是一个链表&#xff0c;它也是实现List接口的一个类。LinkedList就是通过next引用将所有的结点链接起来&#xff0c;所以不需要数组。LinkedList也是以泛型的方法实现的&#xff0c;所以使用这个类都需要实例化对象。 链表分为很多种&#xff0c;比…