「浙江理工大学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 { ...
随机推荐
- Python小游戏——外星人入侵(保姆级教程)第一章 03设置飞船图片 04创建Ship类
系列文章目录 第一章:武装飞船 03:设置飞船图片 04:创建Ship类--管理飞船行为的类 一.设置飞船图片 1.注意事项 A.将图片设置为位图bmp格式最简单,因为pygame默认加载位图 B.飞 ...
- CSP2021-S游记
前言 年纪大了,脑子乱了,渐渐被低年级吊打了. 大家这么内卷下去,高年级的普遍后悔自己生早了,低年级永远占优势,不只是机会优势,还有能力优势. 快进到改变基因出生国家队算了-- Day0 非常不幸地被 ...
- PHP实现获取本地视频进行随机播放
创建一个文件夹,里面随便方视频文件即可 列如文件夹名字是assets代码如下 <? $handler = opendir('./assets/mp4/');//当前目录中的文件夹下的文件夹 需要 ...
- 【Java】学习路径58-TCP聊天-双向发送实现
这一章内容比较复杂(乱) 重点在于解决利用TCP协议实现双向传输. 其余的细节(比如end)等,不需要太在意. 但是我也把折腾经历写出来了,如果大家和我遇到了类似的问题,下文可以提供一个参考. 目标: ...
- 【java】非常多!学习路径24-总结目前所有知识(上)
感谢sikiedu.com的siki老师.几年前就开始看siki的课程,最近突然想写这个笔记系列,顺便回顾一下这些基础的知识,同时也希望能帮助到一些人,有问题一起交流哈. 全文共十章,大约1.5万字, ...
- KingbaseES V8R6集群维护案例之--单实例数据迁移到集群案例
案例说明: 生产环境是单实例,测试环境是集群,现需要将生产环境的数据迁移到集群中运行,本文档详细介绍了从单实例环境恢复数据到集群环境的操作步骤,可以作为生产环境迁移数据的参考. 适用版本: Kingb ...
- Java 将Excel转为UOS
以.uos为后缀的文件,表示Uniform Office Spreadsheet文件,是一种国产的办公文件格式,该格式以统一办公格式(UOF)创建,使用XML和压缩保存电子表格.既有的Excel表格文 ...
- Docker安装Redis并使用Another Redis Desktop Manager连接
Redis简单介绍 Redis全称是Remote DIctionary Service,即远程字典服务.Redis 是一个使用C语言编写的.开源的(遵守 BSD 协议).高性能的.支持网络.可基于内存 ...
- Java SE final关键字
final关键字 final可以修饰类.属性.方法和局部变量 如下情况,可以使用final 当不希望类被继承时,可以用final修饰 当不希望父类的某个方法被子类覆盖/重写(override)时,可以 ...
- 【项目实战】Kaggle泰坦尼克号的幸存者预测
前言 这是学习视频中留下来的一个作业,我决定根据大佬的步骤来一步一步完成整个项目,项目的下载地址如下:https://www.kaggle.com/c/titanic/data 大佬的传送门:http ...