洛谷P1009题解(全AC)

C++洛谷题解(34)——P1009 题号:P1009,题名:阶乘之和 阅读详情

一、题目描述

用高精度计算出 S=1!+2!+3!+⋯+n!S=1!+2!+3!+⋯+n!(n≤50n≤50)。

其中 ! 表示阶乘,定义为 n!=n×(n−1)×(n−2)×⋯×1n!=n×(n−1)×(n−2)×⋯×1。例如,5!=5×4×3×2×1=1205!=5×4×3×2×1=120。

二、思路分析

读完题目我们了解到,计算的模块分为累加和累乘两部分。这题需要注意的是以下这句话:

【数据范围】

对于 100% 的数据,1≤n≤50。

而int的取值范围为: -2^31——2^31-1,即-2147483648——2147483647,约2*10E9。

而50的阶乘远远超过这个范围...

50!=31035053229546199656252032972759319953190362094566672920420940313

即3*10E64

所以哪怕我们舍弃了int,使用unsign int也是不够的。那么我们该怎样才能最大程度地省下内存呢?这种情况我们就需要用到高精度的写法——

用字符串对每个数位的数字进行记录,再把它们拼接起来。

[?]但是内存是怎么省下来的呢?

int a = 30000;    //创建30000个字节空间!
int b[6] = {3,0,0,0,0};    //创建6个字节空间~ 
//tips:多开一个空间是为了接收'\0'

高精真是很好的算法呢~

我们先用常规算法来一遍累加累乘。

2.1 累乘部分

n! = 1*2*3*...*n

计算这个阶乘并不困难。我们只需要for循环、1个存储量和1个变量就够了。

int n,jc=1;    //jc记得要初始化!!
scanf("%d",&n);
for(int i=2;i<=n;i++){    //可以从2开始乘哦,记得别漏了最后的n
    jc *= i;
}

2.2 累加部分

S(n) = 1! + 2! + ... + n!

最容易想到的是,创建数组jc[n],jc[0] = 1! , jc[1] = 2! ...

但这样意味着阶乘需要多次从1开始计算,太浪费内存了。

所以我们每升一次阶就加到总和sum里面。即:

int sum = 0;
for(int i=1;i<=n;i++){
    jc *= (i+1);    //由i!升阶变成(i+1)!
    ...
    //得到jc = (i+1)!
    sum += jc;
}

累加和累乘的部分就这样完成啦,so easy。但这都是使用int型的数据,因为当阶乘阶数过高时数据会溢出,所以拿不到全AC。

现在我们需要的就是——高精度算法。

前面我们讲了高精度是把每位的数字分别存到数组中,因此高精度的读取和加减乘除方式也会和常规有所不同。

2.3 高精度

2.3.1 高精度-读取

高精度的读取遵循从低位到高位的原则。先来串代码,再进行讲解

int i;
int a[101]    //最多可容纳100数位
int aL=0;
//输入mv
    while(i>0){	
        a[aL++] = i%10;
        //等价于
        //{
        //    a(aL) = i%10;
        //    aL++;
        //}
        i /= 10;
	}

我们需要三个变量,分别用来最初输入(i)、记录数位总长(aL)和存储大数(a)。

值得注意的是,输入数中较高的数位数字会存储到数组中靠后的位置。

举个例子,如果存入三位数,那么百位的数字会存储在a[2],而个位在a[0]。

因此最后我们输出大数的时候,也要从数组的末项向首项输出。

2.3.2 高精度-加法

高精度的加法和我们小学学过的竖式计算很相像。

个位+个位,十位+十位………超过10就进位~ awa

假如我们需要两个三位数相加,这样写就可以啦。

for(int ai=0;ai<aL;ai++){    
//ai和bi分别是a数组与b数组内部的指针
//(不是那个带*的哈,这里只是比喻)
    for(int bi=0;bi<bL;bi++){
        i = max(ai,bi);    //避免a数的数位位少于b数的数位,造成加错位置的问题
        c[i] = a[i]+b[i];
    }
}

2.3.3 高精度-进位

大体思路是把本位数字除以10,余数加给下一位数字,商留在本位。

写成程序就是这样的:

//reg的进位和长度
		for(int i=0;i<regL;i++){
			if(reg[i]>9){    //大于9就进位
				reg[i+1] += reg[i]/10;    //商加到高位
				reg[i] %= 10;    //余数留在本位
			}
		}

2.3.4 高精度-乘法

三位数*三位数,极限长度是六位数->n位*n位*<2n位。

所以我们写成:


	for(int a=0;j<aL;a++){	
		for(int b=0;h<=bL;b++){	
			reg[bi+ai] += b[bi]*a[ai];
		}
	}

2.4 清空储存器

这里我们需要用到memset()函数,用来将指定大小的内存块设定为指定值。

//清空升阶器
	memset(reg,0,sizeof(reg));	//将指定大小的内存块设定为指定值

上图的代码用于将reg数组起的sizeof(reg)个字符的位置的值全设置为0

最后用for循环传值给总和即可~

下图为整体代码:

#include <bits/stdc++.h>
using namespace std;
//定义参数
int n;	
//四个机器:升阶器、阶乘、寄存器、总存器
int lv[100],st[100],reg[100],tot[100];
//四个机器的长度
int lvL,stL=1,regL=1,totL;
//极限长度
int exL=1;

int main(){
	st[0] = 1;	//初始化
	cin >> n;	
	//求S(n). S(n)=1!+2!+...+n!
	for(int i=1;i<=n;i++){
		lvL = 0;	//刷新lvL
		int mv = i;

		//输入i
		while(mv>0){	//覆盖旧lv(刷新)
			lv[lvL++] = mv%10;
			mv /= 10;
		}

		//(i-1)! * i = i!
		for(int j=0;j<lvL;j++){	
			for(int h=0;h<=stL;h++){	//[?]h<stL
				reg[h+j] += st[h]*lv[j];
			}
		}

		//reg的进位和长度
		for(int i=0;i<regL;i++){
			if(reg[i]>9){
				reg[i+1] += reg[i]/10;
				reg[i] %= 10;
			}
		}

		//reg最高位刷新(n<=50,不可能连进两位)
		if(reg[regL]){
			regL++;
		}

		//本次阶乘值转移到寄存器
		totL = stL;	//记录stL,以便计算总和应取的长度
		exL = max(exL,regL);
		for(int i=0;i<regL;i++){
			st[i] = reg[i];
		}
		stL = regL;
		regL = totL+lvL;
		//清空升阶器
		memset(reg,0,sizeof(reg));	//将指定大小的内存块设定为指定值

		//传值给总和
		for(int i=0;i<exL;i++){
			tot[i] += st[i];
			if(tot[i]>9){
				tot[i+1] += tot[i]/10;
				tot[i]%=10;
			}
		}
	}
	while(tot[exL]==0 && exL>0) exL--;
	for(int i=exL;i>=0;i--){
		cout << tot[i];
	}
	return 0;
}

感谢阅读~Thanks♪(・ω・)ノ

from 一名小程序员 三鸽

 

洛谷P1009阶乘之和C语言实现 代码如下 #include <stdio.h> #include <stdlib.h> long result(int n) { if(n<0) return -1; else return(n*result(n-1)); } int main() { int n,i,sum=0; scanf("%d",&n); for(i=0;i<n;i++) { sum += r 阅读详情

相关推荐

题解:洛谷 B2034 计算 2 的幂

等知名刷题平台精心挑选而来,并结合各平台提供的算法标签和难度等级进行了系统分类。题目涵盖了从基础到进阶的多种算法和数据结构,旨在为不同阶段的编程学习者提供一条清晰、平稳的学习提升路径。进行输出,您需要关注被输出的数据的类型。输出格式不符合预期可能会造成答案错误。您可以使用显式或隐式的类型转换,来变换数据类型。例如,您可以在这两个网站中查到。常用函数的返回值类型可以在。请注意,如果您正在使用。本文分享的必刷题目是从。#入门# #语法基础#

团爸讲算法 1049

洛谷P1009 [NOIP1998 普及组] 阶乘之和(C语言)AC代码带注释详解

题目描述 用高精度计算出S = 1! + 2! + 3! + \cdots + n!S=1!+2!+3!+⋯+n!(n \le 50n≤50)。 其中“!”表示阶乘,例如:5! = 5 \times 4 \times 3 \times 2 \times 15!=5×4×3×2×1。 输入格式 一个正整数nn。 输出格式 一个正整数SS,表示计算结果。 输入输出样例 输入 #1复制 3 输出 #1复制 9 说明/提示 【数据范围】 对于100 \%100%的数据,1...

Prudento的博客 6370

帝国CMS v7.5存储型XSS漏洞挖掘与修复实战

存储型XSS(跨站脚本攻击)是一种常见的Web安全漏洞,其核心原理是攻击者将恶意脚本代码提交并永久存储在服务器端(如数据库),当其他用户访问包含该数据的页面时,脚本会在其浏览器中执行。这种漏洞的危害在于其持久性和广泛的影响范围,可能导致用户Cookie被窃取、会话被劫持,甚至引发蠕虫式传播。从技术价值看,理解存储型XSS有助于掌握Web应用安全的核心逻辑,即数据在输入、处理和输出全链路中的安全风险。在内容管理系统(CMS)等Web应用场景中,用户可控的输入点(如个人资料、评论、公告)若未经妥善过滤和输出编码

weixin_29327525的博客 299

洛谷P1009 [NOIP1998 普及组] 阶乘之和(C语言)

【代码】洛谷P1009 [NOIP1998 普及组] 阶乘之和(C语言)

2301_80267323的博客 1319

自锁电路设计

Hi,uu们,是不是经常要用到自锁电路,通常不是使用555芯片就是用比较器来做自锁,今天我们来简单看下自锁电路的设计.图1采用了比较器构建了一个自锁电路,采用低电平复位,当需要复位的时候志需要将反向端的二极管拉低一下即可,免去 三极管控制同相端和电源短接的麻烦。图1:比较器构建的自锁电路也可以使用555去构建,如下图2所示.图2:使用555构建的自锁电路工作原理见555的真值表,真值表如表1所示.表1:555电路真值表相对来说555还是比较贵,所以我就想能不能有个便宜的方法做个自锁电路,构建电路如下图3所示

weixin_43884675的博客 7067

DMA+Timer 生成 PWM 波形错位问题分析与解决

本文深入分析了DMA与Timer协同生成PWM波形时出现的错位问题,揭示了DMA传输启动时机与定时器溢出中断的微妙关系。通过占空比强制清零法和预装载值调校技巧,提供了有效的解决方案,并总结了PWM+DMA配置的最佳实践,帮助开发者避免类似问题。

weixin_29191081的博客 349

洛谷P1009 (解放双手的探索)

Description 用高精度计算出S=1!+2!+3!+…+n! (n≤50)S=1!+2!+3!+…+n!(n≤50) 其中“!”表示阶乘,例如:5!=5 \times 4 \times 3 \times 2 \times 15!=5×4×3×2×1。 Input 一个正整数NN。 Output 一个正整数SS,表示计算结果。 Input Sample 3 Output Sample ...

weixin_44090305的博客 1443

保姆级教程:用中移ML307模组对接高德/OneOS定位服务,从配置apikey到解析+MLBSLOC状态码

本文详细介绍了如何使用中移ML307系列模组对接高德/OneOS定位服务,从配置apikey到解析+MLBSLOC状态码的全过程。涵盖高德定位服务和OneOS定位服务的配置步骤、常见错误处理及性能优化技巧,帮助开发者快速实现基站定位功能,提升物联网项目的定位精度和稳定性。

weixin_30632089的博客 508

洛谷P1009题解

本蒟蒻的第一篇题解,还请各位大牛多指教。 题目要求输入n,求出1~n每个数的阶乘之和S。那我们就可以得出代码: #include<bits/stdc++.h>//万能头文件 using namespace std; long long n,ans,t=1;//t用于存储每个数的阶乘 int main(){ //输入 cin>>n; //计算 for(int i=1;i<=n;i++){ t*=i;//计算当前数的阶乘 ans+=t;//求和

vccwx的博客 749

基于Harness Engineering构建AI Agent的全自动化CI_CD流水线

AI Agent的CI/CD是指对Agent的全生命周期资产(代码、Prompt、RAG知识库、模型权重、工具配置)进行持续集成、持续测试、持续发布和持续观测的自动化流程,核心目标是在保障发布质量的前提下,最大化提升Agent的迭代效率。

AI云原生与云计算技术学院 625

LoRa双端通信稳定性核心:同步字配置与LLCC68工程实践

LoRa是一种基于扩频调制的远距离低功耗无线通信技术,其物理层鲁棒性依赖于发射端与接收端在频率、带宽、扩频因子及同步字等关键参数上的严格一致。同步字作为LoRa帧结构中位于前导码之后的2字节标识字段,承担着物理层帧过滤与网络隔离的核心作用,直接影响通信成功率与抗干扰能力。在实际嵌入式开发中,尤其采用LLCC68等专用射频芯片时,同步字配置错误或双端不一致是导致‘能发不能收’‘间歇性丢包’等典型问题的首要原因。本文面向STM32等Cortex-M平台开发者,结合硬件一致性约束、驱动移植方法论与寄存器级调试手段

weixin_36019375的博客 130

洛谷P1601 P1303 P1009题解

以上就是洛谷P1601 P1303 P1009题解的全部内容。希望对你有所帮助。如果有任何问题,欢迎交流。

2502_93915572的博客 399

基于Solidworks的三维光路结构示意图绘制实例演示-技术细节

基于Solidworks的三维光路结构示意图绘制实例演示-技术细节

简单光学 1万+

c语言p1009阶乘代码,洛谷 P1009 阶乘之和

2019.8.7Mr^Simon蒟蒻水题T3解题思路:高精度水题AC代码:1 #include2 #include3 using namespace std;4 int a[2000];5 int b[2000];6 int c[2000];7 int sum[2000];8 void pplus(int *a,int *c)9 {10 int jw = 0;11 for(int ...

weixin_28761725的博客 759

【学习系列】SAP RAP 7:行为定义-Draft

本文介绍了RAP框架中的草稿表(Draft)功能及其应用。草稿表允许用户临时保存数据,在激活前不影响业务逻辑,支持保存继续、暂存和设备切换功能。草稿分为独占草稿(仅限同一用户编辑)和协作草稿(允许多用户协同编辑)。启用草稿需在行为定义和投影中包含标准action,并创建包含TotalETag等管理字段的草稿表。TotalETag确保草稿转换时活动数据未被修改,而ETagmaster则防止并发修改。文章通过OData调用示例详细说明了ETag验证过程,强调草稿功能由RAP框架自动处理,开发者只需关注定义和配置

DeveloperMrMeng的博客 443

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

洛谷P1009 阶乘之和-Go语言

洛谷P1009 阶乘之和-Go语言 P1009 [NOIP1998 普及组] 阶乘之和 题目描述 用高精度计算出 S=1!+2!+3!+⋯+n!(n≤50)。 其中“!”表示阶乘,例如:5!=5×4×3×2×1。 输入格式 一个正整数 n。 输出格式 一个正整数 S,表示计算结果。 输入 #1 3 输出 #1 9 说明/提示 【数据范围】 对于 100% 的数据,1≤n≤50。 AC代码 package main import ( "fmt" "strconv" ) func add(s1, s

qq_22328011的博客 390

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

【题解·洛谷】P1009 [NOIP1998 普及组] 阶乘之和

洛谷P1009 题解

qq_56897740的博客 1182

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

洛谷P1865题解

讲一下一道题的题解

kirihara233的博客 368

python教程1009python教程_P1009 阶乘之和(python)解题报告

笔者的第一语言为C++,初学python,代码如有可改进之处,欢迎讨论(不过代码都已经过测评且AC) -----------Check_XY引言放暑假了,终于有空余时间自学一下python(虽然物竞、数竞和文化课几乎挤扁了我的空余时间)就从我以前刷过的C++的题开始吧以前为OI刷题的时候,并没有养成经常写解题报告的习惯经过一番考虑,决定记录我的python解题,此随笔为第二弹原题链接(洛谷P10...

weixin_42244017的博客 213

洛谷刷题 P1009 [NOIP1998 普及组] 阶乘之和

比如,我们用字符串记录1234这个数字时,我们会构造一个char 数组 listA,然后令listA [0] = ‘4’,listA [1] = ‘3’,listA [2] = ‘2’,listA [3] = ‘1’,此时我们是按反方向存储了1234,至于为何,接下来会说明,接着我们用相同方式,用listB存储9876。在这道题中,我们的阶乘可以从上一个阶乘结果基础上乘一个int类型数得到,主要思想与加法类似,就是高精度的每位乘上乘数加上上一位的进位,得到result对应位数上的数字。

Kenjuan的博客 623

【洛谷题单】洛谷入门3 循环结构

这样命名的好处就是,可以在声明结构体的时候调用该初始化函数,

m0_62216705的博客 1009

洛谷P1009[NOIP1998 普及组] 阶乘之和 解析及AC代码

用高精度计算出 S = 1! + 2! + 3! + ……+ n! S=1!+2!+3!+⋯+n!(n≤50)。

flyunicorninsky的博客 264

洛谷题解 P1009 [NOIP1998 普及组] 阶乘之和

高精度加法以及高精度乘法( ) 简略的题目,简略的算法,不一样的数据,此题的数据很显然不能用longlong或者unsignedlonglong类型,因为还是会上溢,题目也说了,要求高精度算法 没啥好说的( ) 在做题之前,我们先来看看什么是高精度计算,为什么需要高精度计算?那么我们粗略的知道了,对于高精度计算,对应着大整数之间或者对精度高要求的计算。此题便要我们实现高精度乘法以及加法。 做法就是每次乘完都来次进位,模仿竖式运算( )

kwslo的博客 456

洛谷-循环结构(1)

给出n和n个整数ai​,求这n个整数中最小值是什么。

2403_87587520的博客 1352

洛谷 P1009 阶乘之和

题目传送门 2019.8.7Mr^Simon蒟蒻水题T3 解题思路: 高精度水题 AC代码: 1 #include<iostream> 2 #include<bits/stdc++.h> 3 using namespace std; 4 int a[2000]; 5 int b[2000]; 6 int c[2000]; 7...

anshuo0835的博客 191

【洛谷】【高精度】P1009 [NOIP1998 普及组] 阶乘之和

题目链接:https://www.luogu.com.cn/problem/P1009 题目描述 用高精度计算出 S = 1! + 2! + 3! + …+ n!(n≤50)。 其中“!”表示阶乘,例如:5!=5×4×3×2×1。 输入格式 一个正整数 n。 输出格式 一个正整数 S,表示计算结果。 测试样例 输入 3 输出 9 解题思路 1.要注意高精度,可能会想到用__int128,但是当你算到45的阶乘是就会发现这个也不够用了,而且算的很慢,不如自己手写一个高精度,我在这里用的是一个一位数组。 2

要像蜗牛一样一步一步往上爬! 2077
上一篇: 洛谷P1055题解(全AC)
下一篇: 洛谷P1217题解(全AC)
三个鸽Ge
博客等级 码龄6年 47粉丝 11原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值