首页 > 编程语言 >「浙江理工大学ACM入队200题系列」问题 L: 零基础学C/C++52——计算数列和2/1,3/2,5/3,8/5......

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

时间:2022-09-24 12:35:30浏览次数:48  
标签:分子 200 变量 int ...... long 入队 整数 分母

本题是浙江理工大学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成员群中提问哦!

标签:分子,200,变量,int,......,long,入队,整数,分母
From: https://www.cnblogs.com/gemini-star/p/zstuACM200_5L.html

相关文章

  • ORA-20011 ORA-29913 KUP-11024故障处理
    在日常巡中发现alert日志有出现ORA-20011:ApproximateNDVfailed:ORA-29913:errorinexecutingODCIEXTTABLEOPENcalloutKUP-11024:Thisexternaltablecanonl......
  • 做题记录整理dp11 P4158 [SCOI2009]粉刷匠(2022/9/23)
    P4158[SCOI2009]粉刷匠事实上前半个小时我甚至没想用dp做。。。感觉这道题难度标高了(跟那个想让我测出题人的码的题相比)首先可以发现每一行之间都是独立的,所以先考虑把......
  • 做题记录整理dp9 P1758 [NOI2009] 管道取珠(2022/9/23)
    P1758[NOI2009]管道取珠这道题的难点就在于赋予ai的平方和一个具体的含义,我们可以想到(其实要不是上课听了根本想不到)ai的平方和其实就是两个管道取珠游戏一起玩,然后取......
  • 做题记录整理dp810 P2254 [NOI2005] 瑰丽华尔兹(2022/9/23)
    P2254[NOI2005]瑰丽华尔兹题解这题的难点在与dp的递推方程的书写如果写对了递推方程,想到单调队列优化是很自然的(然而我想到了不会打)还有递推方程的具体代码实现也挺......
  • QL Server 2005性能计数器错误的解决办法
    查看安装帮助后,发现有这一段话:1在MicrosoftWindows2003或WindowsXP桌面上,依次单击“开始”、“运行”,然后在“打开”中键入regedit.exe,再单击“确定”。在......
  • 3rd 2022/5/9 题目总结·数论篇·欧拉函数·【SDOI2008】仪仗队
    原题作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N*N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的生后方,根据其视线所及的学生人数......
  • 【线性dp】 [SCOI2009]粉刷匠
    点个关注点个赞吧一道比较简单的线性dp题目前置知识:会手推一些简单的状态转移方程、较为熟练地掌握背包问题模型[SCOI2009]粉刷匠题目描述windy有\(N\)条木......
  • [NOIP2002 提高组] 字串变换
    [NOIP2002提高组]字串变换题目背景本题疑似错题,不保证存在靠谱的多项式复杂度的做法。测试数据非常的水,各种做法都可以通过,不代表算法正确。因此本题题目和数据仅供参......
  • [P3445] [POI2006] TAN - Dancing in Circles
    神仙题目!!!感谢程老师完成了几乎所有的证明过程。首先注意到模数是\(2005\),去掉模数似乎很不可做,所以大胆猜测正解依赖模数。不难发现,把\(n\)个人分成\(k_1\)个大小为......
  • 英伟达2000TOPS大算力与云端芯片
    英伟达2000TOPS大算力与云端芯片参考文献链接https://mp.weixin.qq.com/s/oi14v83S_0iUBY31xqvjPQhttps://mp.weixin.qq.com/s/HkfgdaVJoaX7N_3IXGXwLAhttps://mp.weix......