【题目链接】

ybt 1173:阶乘和
注:一本通上这题,应该把n≤50n\le50n≤50当做n≤100n\le100n≤100来看
OpenJudge NOI 1.6 15:阶乘和
洛谷 P1009 [NOIP1998 普及组] 阶乘之和

【题目考点】

1. 高精度

考察:高精乘低精 高精加高精
高精度计算讲解

【解题思路】

相应的低精度数字求阶乘和的解法如下:
ybt 1091:求阶乘的和
采用其中复杂度为O(n)O(n)O(n)的迭代法,代码如下:

#include <bits/stdc++.h>
using namespace std;
int main()
{int n;cin >> n;int s = 0, a = 1;//a:某一阶乘项的值 for(int i = 1; i <= n; ++i){a *= i;//本句运行结束后,a的值为i! s += a;//加和变量中增加i! }cout << s;return 0;
}

在本问题中,s与a应该是高精度数字,i,n是低精度数字。a*=i为高精乘低精,s+=a为高精加高精。
该题难点在于分析结果位数,为数字数组设一个合理的数组长度。(比如不知道结果位数,就设了数组长为10000,那你凭什么认为结果一定小于10000位?总得有点根据吧。)
求数字位数公式:假设数字x有n位,那么n=⌊lgx⌋+1n = \lfloor lgx \rfloor + 1n=⌊lgx⌋+1
假设n=50,求1!+2!+...+50!1!+2!+...+50!1!+2!+...+50!的位数,我们可以不断将结果放大
1!+2!+...+50!≤50∗50!≤50∗5050=50511!+2!+...+50! \le 50*50! \le 50*50^{50}=50^{51}1!+2!+...+50!≤50∗50!≤50∗5050=5051
求505150^{51}5051的位数:⌊lg5051⌋+1=⌊51∗lg50⌋+1≤⌊51∗lg100⌋+1=103\lfloor lg50^{51} \rfloor + 1 = \lfloor 51*lg50 \rfloor + 1 \le \lfloor 51*lg100 \rfloor + 1 = 103⌊lg5051⌋+1=⌊51∗lg50⌋+1≤⌊51∗lg100⌋+1=103
将数字数组长度设为105就可以满足要求。
【注】一本通OJ上本题测试数据有误,需要将数字数组长度设为155才能过(我只试到155能过),否则有几个测试点会报“运行错误”。所以可以当这道题中给定的n≤50n\le50n≤50当做n≤100n\le100n≤100来看,这样推算出的数据位数就没有问题了。

【题解代码】

解法1:使用函数与数组

本解法中,使用的高精度运算为 a*=b和a+=b。

#include<bits/stdc++.h>
using namespace std;
#define N 155//一本通OJ上必须设为155才能过 洛谷、OpenJudge上设到105就能过
void Multiply(int a[], int b)//高精乘低精 a *= b
{int c = 0, i;for(i = 1; i <= a[0]; ++i){a[i] = a[i]*b + c;c = a[i] / 10;a[i] %= 10; }while(c > 0){a[i] = c % 10;c /= 10;i++;}while(a[i] == 0 && i > 1)i--;a[0] = i;
}
void Add(int a[], int b[])//高精加高精 a += b
{int c = 0, i;for(i = 1; i <= a[0] || i <= b[0]; ++i){a[i] += b[i] + c;c = a[i] / 10;a[i] %= 10;}if(c > 0)a[i] = c;while(a[i] == 0 && i > 1)i--;a[0] = i;
}
void showNum(int a[])
{for(int i = a[0]; i >= 1; --i)cout << a[i];
}
int main()
{int a[N] = {1, 1}, s[N] = {1, 0}, n;//数字a初值为1 加和s初值为0 cin >> n;for(int i = 1; i <= n; ++i){Multiply(a, i);Add(s, a);}showNum(s);return 0;
}

解法2:类中重载运算符

#include<bits/stdc++.h>
using namespace std;
#define N 155
struct HPN
{int a[N];HPN(){memset(a, 0, sizeof(a));}HPN(char s[]){memset(a, 0, sizeof(a));a[0] = strlen(s);for(int i = 1; i <= a[0]; ++i)a[i] = s[a[0] - i] - '0';}int& operator [] (int i){return a[i];}void setLen(int i)//确定数字位数{while(a[i] == 0 && i > 1)i--;a[0] = i;}void operator *= (int b)//a *= b{int c = 0, i;for(i = 1; i <= a[0]; ++i){a[i] = a[i]*b + c;c = a[i] / 10;a[i] %= 10; }while(c > 0){a[i] = c % 10;c /= 10;i++;}setLen(i); }void operator += (HPN b)//高精加高精{int c = 0, i;for(i = 1; i <= a[0] || i <= b[0]; ++i){a[i] += b[i] + c;c = a[i] / 10;a[i] %= 10;}a[i] = c;setLen(i);}void show(){for(int i = a[0]; i >= 1; --i)cout << a[i];}
};
int main()
{int n;cin >> n;HPN s("0"), a("1");//s = 0, a = 1 for(int i = 1; i <= n; ++i){a *= i;//高精乘低精s += a;//高精加高精}s.show();return 0;
}

信息学奥赛一本通 1173:阶乘和 | OpenJudge NOI 1.6 15 | 洛谷 P1009 [NOIP1998 普及组] 阶乘之和相关推荐

  1. 洛谷——P1009 [NOIP1998 普及组] 阶乘之和

    P1009 [NOIP1998 普及组] 阶乘之和 题目描述 用高精度计算出 S = 1! + 2! + 3! + \cdots + n!S=1!+2!+3!+⋯+n!(n \le 50n≤50). ...

  2. 信息学奥赛一本通 1233:接水问题 | 1950:【10NOIP普及组】接水问题 | OpenJudge NOI 1.9 15 | 洛谷 P1190 [NOIP2010 普及组] 接水问题

    [题目链接] ybt 1233:接水问题 ybt 1950:[10NOIP普及组]接水问题 OpenJudge NOI 1.9 15:接水问题 洛谷 P1190 [NOIP2010 普及组] 接水问题 ...

  3. 信息学奥赛一本通 1179:奖学金 | 1938:【07NOIP普及组】奖学金 | OpenJudge NOI 1.10 04 | 洛谷 P1093 [NOIP2007 普及组] 奖学金

    [题目链接] ybt 1179:奖学金 ybt 1938:[07NOIP普及组]奖学金 OpenJudge NOI 1.10 04:奖学金 洛谷 P1093 [NOIP2007 普及组] 奖学金 [题 ...

  4. 信息学奥赛一本通 1180 | 1946:【09NOIP普及组】分数线划定 | OpenJudge NOI 1.10 05 | 洛谷 P1068 [NOIP2009 普及组] 分数线划定

    [题目链接] ybt 1180:分数线划定 ybt 1946:[09NOIP普及组]分数线划定 OpenJudge NOI 1.10 05:分数线划定 洛谷 P1068 [NOIP2009 普及组] ...

  5. 信息学奥赛一本通 1184 | 1934:【06NOIP普及组】明明的随机数 | OpenJudge NOI 1.10 09 | 洛谷 P1059 [NOIP2006 普及组] 明明的随机数

    [题目链接] ybt 1184:明明的随机数 ybt 1934:[06NOIP普及组]明明的随机数 OpenJudge NOI 1.10 09:明明的随机数 洛谷 P1059 [NOIP2006 普及 ...

  6. 信息学奥赛一本通 1958:【12NOIP普及组】寻宝 | OpenJudge NOI 1.12 06 | 洛谷 P1076 [NOIP2012 普及组] 寻宝

    [题目链接] ybt 1958:[12NOIP普及组]寻宝 洛谷 P1076 [NOIP2012 普及组] 寻宝 OpenJudge NOI 1.12 06:寻宝 [题目考点] 1. 模拟 2. 循环 ...

  7. 信息学奥赛一本通 1111:不高兴的津津 | 1926:【04NOIP普及组】不高兴的津津| OpenJudge NOI 1.9 03 | 洛谷 P1085 [NOIP2004 普及组] 不高兴的津津

    [题目链接] ybt 1111:不高兴的津津 ybt 1926:[04NOIP普及组]不高兴的津津 OpenJudge NOI 1.9 03:不高兴的津津 洛谷 P1085 [NOIP2004 普及组 ...

  8. 信息学奥赛一本通 1107:校门外的树 | 1931:【05NOIP普及组】校门外的树 | OpenJudge NOI 1.6 06 | 洛谷 P1047 [NOIP2005 普及组] 校门外的树

    [题目链接] ybt 1107:校门外的树 ybt 1931:[05NOIP普及组]校门外的树 OpenJudge NOI 1.6 06:校门外的树 洛谷 P1047 [NOIP2005 普及组] 校 ...

  9. 信息学奥赛一本通 1103:陶陶摘苹果 |1930:【05NOIP普及组】陶陶摘苹果 | OpenJudge NOI 1.6 02 | 洛谷 P1046 [NOIP2005 普及组] 陶陶摘苹果

    [题目链接] ybt 1103:陶陶摘苹果 ybt 1930:[05NOIP普及组]陶陶摘苹果 OpenJudge NOI 1.6 02:陶陶摘苹果 洛谷 P1046 [NOIP2005 普及组] 陶 ...

最新文章

  1. python表单防重复提交_防止表单重复提交的几种策略
  2. 深度优先遍历_二叉树的深度优先遍历,理解框架真的能够套用题目吗?不了解执行过程可能很难。...
  3. python编程标准_python编程规范
  4. PHPCMS最新版任意文件上传漏洞分析
  5. jms.jar 2.0_JMS 2.0中JMSContext的类型
  6. (9)verilog语言编写SPI接收
  7. uCharts图表在小程序中的使用
  8. SQLServer常用SQL语句
  9. GAN详解与PyTorch MINIST手写数字生成实战
  10. 身份证号中提取性别、年龄、年月日的Excel(WPS)公式
  11. python火车票自我编写_自己动手写100行Python代码抢火车票!
  12. 数字改造有色金属产业链,发挥产业优势效能
  13. 微信小程序wxs将数字转换为汉字
  14. 华为高性能服务器实验室,1000平米全球唯一!华为神秘实验室首公开
  15. Python安装三方包
  16. 浅谈跨站请求伪造(CSRF)
  17. AmazeUI 文本大小对照表
  18. 邮编区号查询易语言代码
  19. javax.servlet.ServletException: Servlet execution threw an exception org.apache.tomcat.websocket.se
  20. 笔记本电脑关闭小键盘(即打字按P出现星号键)

热门文章

  1. Python中的bytes,str,int等类型转换
  2. FreeRTOS调度器挂起与解除
  3. 命令color_【按键精灵教程】CmpColorEx、FindMultiColor 命令详解
  4. 阿里预面:谈谈你对双亲委派机制的理解?这个名字有啥问题?如何打破?为啥双亲委派?...
  5. SpringBoot 如何生成接口文档,老鸟们都这么玩的!
  6. 4万次下载,我的这本电子书连续数月蝉联阿里云下载榜冠军!!!
  7. 我面试几乎必问:你设计索引的原则是什么?怎么避免索引失效?
  8. 微信淘宝等平台要互通!?腾讯阿里字节回应
  9. 微信第一个“小程序”亮相:不是APP胜似APP!
  10. 微服务架构案例(06):通过业务、应用、技术、存储方面,聊聊架构