当前位置: 首页 > news >正文

P1009 [NOIP 1998 普及组] 阶乘之和

题目描述

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

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

输入格式

一个正整数 n。

输出格式

一个正整数 S,表示计算结果。

输入输出样例

输入 #1复制运行

3

输出 #1复制运行

9

说明/提示

【数据范围】

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

【其他说明】

注,《深入浅出基础篇》中使用本题作为例题,但是其数据范围只有 n≤20,使用书中的代码无法通过本题。

如果希望通过本题,请继续学习第八章高精度的知识。

NOIP1998 普及组 第二题

解题方法:

用高精度加法和高精度乘法结合做。

我们先讲一下为什么用和怎么用高精度加法和乘法;

为什么用高精度加法和乘法:

因为每一个变量类型都是有取值范围的,例如:int型(-2^31~2^31-1),就算是long long型也就(-2^63~2^63-1),所以当数字过大时就容易发生溢出。这里就需要用到高精度加法和高精度乘法。

如何使用高精度加法和乘法:

高精度加法:

1.用两个整型数组分别存储加数和被加数,

先用char数组存储再转为long long数组【reverse就是逆转一下数组】

char str1[500],str2[500];cin>>str1>>str2;long long len1,len2,lenmax,h;len1=strlen(str1);len2=strlen(str2);reverse(str1,str1+len1);reverse(str2,str2+len2);lenmax=len1>len2?len1:len2;vector<long long> array1(500,0);vector<long long> array2(500,0);vector<long long> array(500,0);for(long long i=0;i<lenmax;i++){if(i<len1){array1[i]=str1[i]-'0';}if(i<len2){array2[i]=str2[i]-'0';}}

2.两整型数组中的从低到高的单个数字依次相加,并进位 ,

例如23+99:就是3+9=2进位1,2+9+1=2,进位1;

for(long long i=0;i<lenmax;i++){array[i]+=(array1[i]+array2[i])%10;array[i+1]+=(array1[i]+array2[i])/10;}if(array[lenmax]){lenmax++;}for(long long i=lenmax-1;i>=0;i--){cout<<array[i];}
高精度乘法:

1.用两个整型数组分别存储乘数和被乘数,

先用char数组存储再转为long long数组【reverse就是逆转一下数组】

char str1[500],str2[500];cin>>str1>>str2;long long len1,len2,lenmax,h;len1=strlen(str1);len2=strlen(str2);reverse(str1,str1+len1);reverse(str2,str2+len2);lenmax=len1>len2?len1:len2;vector<long long> array1(500,0);vector<long long> array2(500,0);vector<long long> array(500,0);for(long long i=0;i<lenmax;i++){if(i<len1){array1[i]=str1[i]-'0';}if(i<len2){array2[i]=str2[i]-'0';}}

2.一整型数组中的每一个数字从低到高依次乘以别一数组中的每一个数字。

最终得到的数组中的每一个数字都%10并且进位(/10)

例如:123*321 得数组中第一个a[0]为3*1=3 ,a[1]=2*1+3*2=8 ,a[2]=3*3+2*2+1*1=14等等。

lenmax=len1+len2;for(long long i=0;i<len1;i++){for(long long j=0;j<len2;j++){array[i+j]+=array1[i]*array2[j];}}for(long long i=0;i<lenmax;i++){array[i+1]+=array[i]/10;array[i]=array[i]%10;}if(!array[lenmax-1]){lenmax--;}for(long long i=lenmax-1;i>=0;i--){cout<<array[i];}

那么现在讲讲如何做这一题:

1.首先用高精度乘法计入n个大数字于long long 数组中并且依次计入每一个大数字分别有多少位

例如有3个大数字时,1在a[0][0]中有1位,2在a[1][0]中有1位,6在a[2][0]中有1位,

long long n,length=1;cin>>n;vector<vector<long long> > array(n,vector<long long>(500,0));//array存储的是每一个大数据vector<long long> number(n,0);array[0][0]=1;number[0]=1;//number存储的是每一个大数据有多少位for(long long i=2;i<=n;i++){for(long long j=0;j<length;j++){array[i-1][j]=array[i-2][j]*i;}length+=2;for(long long j=0;j<length;j++){array[i-1][j+1]+=array[i-1][j]/10;array[i-1][j]%=10;}while(1){if(array[i-1][length-1]){break;}else{length--;}}number[i-1]=length;}

2.再用高精度加法对每一个大数据进行相加。【我这里是将array[0]以后的大数据都加在array[0]中,所以array[0]是最终相加数】

for(long long i=1;i<n;i++){for(long long j=0;j<number[i];j++){array[0][j+1]+=(array[0][j]+array[i][j])/10;array[0][j]=(array[0][j]+array[i][j])%10;}}length=number[n-1];if(array[0][length]){length++;}for(long long i=length-1;i>=0;i--){cout<<array[0][i];}
总体代码: 
#include<bits/stdc++.h>
using namespace std;
int main(){long long n,length=1;cin>>n;vector<vector<long long> > array(n,vector<long long>(500,0));vector<long long> number(n,0);array[0][0]=1;number[0]=1;for(long long i=2;i<=n;i++){for(long long j=0;j<length;j++){array[i-1][j]=array[i-2][j]*i;}length+=2;for(long long j=0;j<length;j++){array[i-1][j+1]+=array[i-1][j]/10;array[i-1][j]%=10;}while(1){if(array[i-1][length-1]){break;}else{length--;}}number[i-1]=length;}for(long long i=1;i<n;i++){for(long long j=0;j<number[i];j++){array[0][j+1]+=(array[0][j]+array[i][j])/10;array[0][j]=(array[0][j]+array[i][j])%10;}}length=number[n-1];if(array[0][length]){length++;}for(long long i=length-1;i>=0;i--){cout<<array[0][i];}return 0;
}

以上就是P1009 [NOIP 1998 普及组] 阶乘之和的详细作法,希望对大家有所帮助。

http://www.dtcms.com/a/271298.html

相关文章:

  • HashMap中get()、put()详解
  • 代码审计-shiro漏洞分析
  • Explain关键字
  • rt thread studio 和 KEIL对于使用rt thread 的中间件和组件,哪个更方便
  • Flask3.1打造极简CMS系统
  • VsCode 接入Continue 远程调用(持续扩展 + DeepSeek R1)— 免本地算力
  • ZECN致业:科创微光,照亮技术新征程
  • 200nl2sql
  • Linux建立本地软件仓库
  • 存储服务一NFS文件存储概述
  • 解锁HTML5页面生命周期API:前端开发的新视角
  • debug和release的区别,打印菱形,水仙花数,喝汽水问题,计算求和
  • 从互联网电脑迁移Dify到内网部署Dify方法记录
  • 语音识别核心模型的数学原理和公式
  • http get和http post的区别
  • 【软件工程】tob和toc含义理解
  • 【25软考网工】第十章 (3)网络冗余设计、广域网接入技术
  • Docker 高级管理 -- 容器通信技术与数据持久化
  • mysql 故障检测与处理
  • Linux 测开:日志分析 + 定位 Bug
  • Paimon 原子提交实现
  • 【Linux】Rocky Linux 安装 Docker 与 Docker-Compose
  • AI智能选股,DeepSeek智能分析股票测试
  • 搭建一款结合传统黄历功能的日历小程序
  • C++最小生成树算法详解
  • 人机协同的关键枢纽:软件工程3.0中对象模型与模型驱动的融合路径
  • Vue 3 中父子组件双向绑定的 4 种方式
  • 如何将 AWS EBS 卷从 gp2 批量迁移到 gp3:完整指南
  • 基于Spring Boot+Vue的DIY手工社预约管理系统(Echarts图形化、腾讯地图API)
  • [Pytest][Part 4]多种测试运行方式