「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++52——计算数列和2/1,3/2,5/3,8/5......
本题是浙江理工大学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 long
和double
两个类型,一般我们改用long long
(学过别的语言的朋友注意了,不是long
,在C中大部分情况下long
和int
是一样大的).不过在这道题里我们可以选择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......的更多相关文章
- 「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++85——完美数
本题是浙江理工大学ACM入队200题第八套中的L题 我们先来看一下这题的题面. 题面 题目描述 任何一个自然数的约数中都有1和它本身,我们把小于它本身的因数叫做这个自然数的真约数. 如6的所有真约数是 ...
- 「浙江理工大学ACM入队200题系列」问题 K: 零基础学C/C++84——奇偶ASCII值判断
本题是浙江理工大学ACM入队200题第八套中的K题 我们先来看一下这题的题面. 题面 题目描述 任意输入一个字符,判断其ASCII是否是奇数,若是,输出YES,否则,输出NO; 例如,字符A的ASCI ...
- 「浙江理工大学ACM入队200题系列」问题 J: 零基础学C/C++83——宁宁的奥数路
本题是浙江理工大学ACM入队200题第八套中的J题 我们先来看一下这题的题面. 题面 题目描述 宁宁参加奥数班,他遇到的第一个问题是这样的:口口口+口口口=口口口,宁宁需要将1~9 九个数分别填进对应 ...
- 「浙江理工大学ACM入队200题系列」问题 E: 零基础学C/C++78——求奇数的乘积
本题是浙江理工大学ACM入队200题第八套中的E题 我们先来看一下这题的题面. 题面 输入 输入数据包含多个测试实例,每个测试实例占一行,每行的第一个数为n,表示本组数据一共有n个,接着是n个整数,你 ...
- 「浙江理工大学ACM入队200题系列」问题 F: 零基础学C/C++39——求方程的解
本题是浙江理工大学ACM入队200题第四套中的F题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...
- 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排序与选择排序算法)
本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习 ...
- 「浙江理工大学ACM入队200题系列」问题 H: 零基础学C/C++18——三位数反转
本题是浙江理工大学ACM入队200题第二套中的H题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...
- 「浙江理工大学ACM入队200题系列」问题 B: 零基础学C/C++12——求平均值
本题是浙江理工大学ACM入队200题第二套中的B题 我们先来看一下这题的题面. 由于是比较靠前的题目,这里插一句.各位新ACMer朋友们,请一定要养成仔细耐心看题的习惯,尤其是要利用好输入和输出样例. ...
- [Python] 文科生零基础学编程系列二——数据类型、变量、常量的基础概念
上一篇:[Python] 文科生零基础学编程系列--对象.集合.属性.方法的基本定义 下一篇: (仍先以最简单的Excel的VBA为例,语法与Python不同,但概念和逻辑需要理解透彻) p.p1 { ...
随机推荐
- JavaScript基础回顾知识点记录4-正则表达式篇(介绍基本使用)
js 中 正则表达式使用 创建正则对象和test方法使用 /* 创建正则表达式的对象 语法: var 变量 = new RegExp("正则表达式","匹配模式" ...
- Swift中的Result 类型的简单介绍
Swift 5引入了一个新的Result类型, 它使用枚举来处理异步函数的结果. 苹果文档对该类型的描述: A value that represents either a success or a ...
- 公网可用的RTMP、RTSP测试地址(2021年3月)
好多博客提到的公网可测试的RTSP和RTMP URL大多都不用了,以下是大牛直播SDK(Github)于2021年3月亲测可用的几个URL,有其他可用的URL,也欢迎大家在评论区回复. RTMP流地址 ...
- KingbaseES 中 JSON 介绍
KingbaseES支持JSON和JSONB.这两种类型在使用上几乎完全一致,主要区别是 JSON类型把输入的数据原封不动的存放到数据库中.JSONB类型在存放时把JSON解析成二进制格式. JSON ...
- KingbaseES R6 集群主库网卡down测试案例
数据库版本: test=# select version(); version ------------------------------------------------------------ ...
- OID 与隐含列
熟悉PostgreSQL的都知道,PG12 开始,不再支持OID伪列.KingbaseES 为了保证与旧版本兼容,特增加了OID 隐含列的支持. R3版本:OID 是整个数据库共用的"序列& ...
- Vim使用技巧(持续更新)
好记性不如烂笔头,在这里记录一些Vim使用技巧 vim配置 "拷贝同步到系统剪切板" set clipboard=unnamed "显示行号" set nu & ...
- 华南理工大学 Python第4章课后小测-1
1.(单选)下面程序的输出结果是: for c in "ComputerScience": print(c,end="") if c=="S" ...
- .NET 反向代理-YARP 部署Https(SSL)
YARP 作为反向代理中间件,那就无可避免需要使用到 Https 去部署项目,那 YARP 要怎么去实现呢,本来以为 YARP 会有一套自己的实现,在翻阅了资料后发现,根本不是我想的那样,按照 YAR ...
- 使用 Loki 微服务模式部署生产集群
转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247500523&idx=1&sn=0994af2b50 ...