本题是浙江理工大学ACM入队200题第五套中的L题

我们先来看一下这题的题面.

题面

题目描述

有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13,…… 计算这个数列的前n项和。注意:C语言中整数/整数的结果为整数;需要用(float)强制转换为实型或乘以1.0后进行计算。

输入

输入一个正整数n。

输出

输出数列的前n项和(保留两位小数),输出格式可为:printf("s=%.2f\n",..);。

样例输入

10

样例输出

s=16.48

提示

C语言中整数/整数的结果为整数;注意用(float)强制转换为实型或乘以1.0后进行计算。


题目分析

都做到这题了,相信对于求和以及整数除整数什么的应该很熟悉了吧?这里就不多赘述了.

观察题目给出的数列,我们发现除第一项以外的每一项的分母是前一项的分子,而分子是前一项的分子和分母之和.这便是这组数列的递推规律,我们可以依照这个递推规律去不断算出每一项.

首先,我们需要定义初始状态,也就是第一项,因为第一项无法使用上面的递推规律.我们定义两个变量a和b,相信大家首选的都是int型,用来分别存放分子和分母,并给予他们第一项的值作为初始值,局部代码如下:

	int a = 2, b = 1; // 初始状态的定义,即第一项

由于是求第n项,我们使用计次循环(for循环)来完成,在循环体中,我们先计算出当前项然后加到累加器中,随后依照前面发现的规律推出下一个状态(即进行状态转移),说人话就是求下一项的分子和分母,局部代码如下:

	for(int i = 0;i < n;i++) // 共循环n次,请习惯i从0开始
{
sum += (double)a / b; // 累加器累加当前项(记得转为小数)
int t = b; // 这里和两个变量交换一样,必须要用临时变量保存其中一个值,不然在更新之后原本的值就消失了
b = a; // 更新分母,下一项的分母即为前一项的分子
a += t; // 更新分子,下一项的分子为前一项的分子(即这个变量本身存的值)和分母(此时分母已被更新,使用临时变量中保存的值)的和
}

如此不断循环理论上就可以推出这个数组的所有项了.这个思路形成很自然,但是其实我们已经在不知不觉中使用了一种非常高级的算法——动态规划(DP).这道题本质上是在动态求斐波那契数列某一项,而这便是DP的典型应用场景.第十八套的问题H也需要使用这种算法,不过和这题一样,即便你不知道什么是DP,你依旧可以很自然地推出能顺利解决那道题的正确思路(因为仁慈的叶教挑的都是简单题,基本不需要你懂很多算法).

DP是一种对新人朋友们来说非常难的算法,这边我只做提及,让大家体会到思维的强大和思想的乐趣,请各位新人朋友们不要继续深入了解,除非你对自己很有信心.就像前面说的那样,即便你不知道什么是DP,即时你不知道你在用DP,你依旧可以很轻松地推出这道题的正确思路.

常见错误思路及原因解析

当前,上述代码仅仅是正确思路而已,如果你就这样直接提交上去,迎接你的是答案错误.


今天又是做梦都是WA的一天呢

这里比较容易出现的一个错误是累加器sum没有初始化,不过你都做到这了,sum还不养成初始化的习惯是不是有点过分了,前面都做了这么多道累加的题了.

除此之外,就是传说中"三年OI一场空,不开long long见祖宗"所描述的典型错误.请大家反复默念并最好背诵这句话.

相信各位朋友应该已经知道了,变量的数据类型本质上是在内存中存储方式,而内存不可能是无限大的,因此在C中每个数据类型都有其范围(Python算是一个特例,它底层实现的高精度等算法允许它的数值型变量存储无限大的数据,只要内存还放得下).在32位系统下,int类型的变量仅能存放4个字节(32个二进制位,其中一个是符号位,所以有效的只有31位)的数据.一旦存放的数据超过4个字节,那么溢出那部分数字就会被直接丢弃.比如你在int里存了33位的数据,那么第33位(最高位)就会直接被无视,你存的是后32位的数据(由于符号位的问题,这个数据经常会很离谱).

此题便是出现了这个问题.大部分题目会给出数据范围,通过数据范围再加上一点点的经验我们可以相对比较容易地发现数据爆int的问题,但对于先前几乎没有遇到过爆int的情况的各位新人朋友们,再加上这道题没有给出数据范围,想独自发现这个错误确实有些困难.我们可以这么思考,我们解决此题的思路没有任何问题,所以只可能是在细节上出了问题,而数据类型是否合适便是其中一个考虑项.养成这样的找错习惯,便可以在一定的思考之后发现这里爆int的问题.

解决方案

解决这个问题的方法非常简单,只要把a和b的数据类型换成一个更大的就好了,这里可选的有long longdouble两个类型,一般我们改用long long(学过别的语言的朋友注意了,不是long,在C中大部分情况下longint是一样大的).不过在这道题里我们可以选择double,这样不仅能解决爆int的问题,还可以解决整数除整数的问题,一石二鸟.不过正常情况下还是建议开成long long,因为浮点数自身还有精度等其他的问题.

参考代码

下面给出了我自己做这道题时候的完整代码:

(仅作为参考,一定要自己写一下奥,作弊没意思,害人又害己)

#include <stdio.h>

int main()
{
int n;
scanf("%d", &n); double sum = 0; // 累加器,别忘了初始化
double a = 2, b = 1; // 初始状态的定义,即第一项
for (int i = 0; i < n; i++) // 共循环n次,请习惯i从0开始
{
sum += a / b;
double t = b; // 这里和两个变量交换一样,必须要用临时变量保存其中一个值,不然在更新之后原本的值就消失了
b = a; // 更新分母,下一项的分母即为前一项的分子
a += t; // 更新分子,下一项的分子为前一项的分子(即这个变量本身存的值)和分母(此时分母已被更新,使用临时变量中保存的值)的和
} printf("s=%.2f\n", sum);
return 0;
}

"正是我们每天反复做的事情,最终造就了我们,优秀不是一种行为,而是一种习惯" ---亚里士多德

这篇题解就到这里了,各位朋友如果有问题欢迎到acm成员群中提问哦!

「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++52——计算数列和2/1,3/2,5/3,8/5......的更多相关文章

  1. 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++85——完美数

    本题是浙江理工大学ACM入队200题第八套中的L题 我们先来看一下这题的题面. 题面 题目描述 任何一个自然数的约数中都有1和它本身,我们把小于它本身的因数叫做这个自然数的真约数. 如6的所有真约数是 ...

  2. 「浙江理工大学ACM入队200题系列」问题 K: 零基础学C/C++84——奇偶ASCII值判断

    本题是浙江理工大学ACM入队200题第八套中的K题 我们先来看一下这题的题面. 题面 题目描述 任意输入一个字符,判断其ASCII是否是奇数,若是,输出YES,否则,输出NO; 例如,字符A的ASCI ...

  3. 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路

    本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...

  4. 「浙江理工大学ACM入队200题系列」问题 E: 零基础学C/C++78——求奇数的乘积

    本题是浙江理工大学ACM入队200题第八套中的E题 我们先来看一下这题的题面. 题面 输入 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你 ...

  5. 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解

    本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  6. 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)

    本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习 ...

  7. 「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转

    本题是浙江理工大学ACM入队200题第二套中的H题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  8. 「浙江理工大学ACM入队200题系列」问题 B: 零基础学C/C++12——求平均值

    本题是浙江理工大学ACM入队200题第二套中的B题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...

  9. [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念

    上一篇:[Python] 文科生零基础学编程系列--对象.集合.属性.方法的基本定义 下一篇: (仍先以最简单的Excel的VBA为例,语法与Python不同,但概念和逻辑需要理解透彻) p.p1 { ...

随机推荐

  1. github action 实现CI/CD

    两种github action 打包.Net Core 项目docker镜像推送到阿里云镜像仓库 1.GitHub Actions 是什么? 大家知道,持续集成由很多操作组成,比如抓取代码.运行测试. ...

  2. 座位安排(欧拉回路,高斯消元,bitset)

    题面 由于旋转大师 F r e n c h \rm French French 的离去, A r e x t r e \rm Arextre Arextre 光荣地承担了给全班换座位的重任. 由于这是 ...

  3. Java中字节流的总结及代码练习

    Java中的字节流 在描述字节流时,先知道什么是流 流可以分为:输入流和输出流 输入流和输出流 示意图: 字节流读取内容:二进制,音频,视频 优缺点:可以保证视频音频无损,效率低,没有缓冲区 字节流可 ...

  4. C#基础_XML文件介绍

    XML简介 XML 被设计用来传输和存储数据. HTML 被设计用来显示数据. 什么是 XML? XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语 ...

  5. OpenJudge 1.5.39 与7无关的数

    39:与7无关的数 总时间限制: 1000ms 内存限制: 65536kB 描述 一个正整数,如果它能被7整除,或者它的十进制表示法中某一位上的数字为7,则称其为与7相关的数.现求所有小于等于n(n ...

  6. JAVA中自定义扩展Swagger的能力,自动生成参数取值含义说明,提升开发效率

    大家好,又见面了. 在JAVA做前后端分离的项目开发的时候,服务端需要提供接口文档供周边人员做接口的对接指导.越来越多的项目都在尝试使用一些基于代码自动生成接口文档的工具来替代由开发人员手动编写接口文 ...

  7. KingbaseES R3 集群主库归档失败案例

    案例说明: 本案例用于KingbaseES R3集群归档进程归档日志失败的处理,对于一线的生产环境具有 一定的参考意义. 数据库版本: TEST=# select version(); VERSION ...

  8. 使用Steamwork.Net 接入Steam一点心得

    1.  前言 这是我在开发过程中使用的一点总结,目前使用的东西包含基础登录功能,存档功能,成就系统,以及DLC安装功能.Steamwork不仅仅有这些功能还有游戏内交易,排行榜,数据传输等功能,这些功 ...

  9. 注解@PostConstruct分析

    作用 1.注解@PostConstruct可以添加在类的方法上面,如果这个类被IOC容器托管,那么在对Bean进行初始化前的时候会调用被这个注解修饰的方法 被定义在哪里? 1.被定义在了CommonA ...

  10. 《Java基础——抽象与接口》

    Java基础--抽象与接口       一.抽象: 规则: 关键字 abstract 修饰的类称为抽象类. 子类通过关键字extends实现继承. 关键字 abstract 修饰的方法称为抽象方法,抽 ...