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

老题新解|求 10000 以内 n 的阶乘

《信息学奥赛一本通》第168题:求10000以内n的阶乘

求10,000以内n的阶乘。
输入:
只有一行输入,整数n(0<=n<=10,000)。
输出:
一行,即n!的值。
样例输入:
100
样例输出:
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000

大家好,我是莫小特。
这篇文章给大家带来《信息学奥赛一本通》中的第 168 题:求 10000 以内 n 的阶乘。

image.png

一、题目描述

求10,000以内n的阶乘。
输入:
只有一行输入,整数n(0<=n<=10,000)。
输出:
一行,即n!的值。
样例输入:
100
样例输出:
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000

二、题意分析

这道题是信息学奥赛一本通练习题的第 168 题。

输入格式为一行一个整数 n,使用 int 类型。

int n;
cin>>n;

对于小的 n(例如 n ≤ 20),直接用 long long 计算 n! 是没问题的,但当 n ≥ 21 时,阶乘的值就已经超过了 long long 的范围。

所以只能使用高精度算法才能实现。

我们知道:

n!=1×2×3×…×nn!=1×2×3×…×nn!=1×2×3××n

我们可以用一个数组 a[] 来保存每一位数字(倒序存储更方便计算),然后依次模拟手工乘法:

(1)初始化a[1] = 1,表示当前结果是 1。

a[1] = 1;           // 初始结果为 1

(2)逐步相乘:依次乘以 2、3、4、…、n。

使用 for 循环实现。

for (int i = 1; i <= n; ++i) // 从 1 乘到 n

(3)模拟竖式乘法

每次循环将 a[j] 乘以当前的 i,再加上上一位的进位,结果对 10 取模存回当前位,商部分作为下一位的进位。

 x = 0;           // 每次从无进位开始
for (int j = 1; j <= len; ++j)
{a[j] = a[j] * i + x; // 当前位乘 i 并加上进位x = a[j] / 10;       // 计算新的进位a[j] %= 10;          // 保留个位数字
}

(4)判断是否需要增加长度:如果进位使得新的一位非零,就增加 len

// 若乘完后还有进位,则继续加位
while (x > 0)
{a[++len] = x % 10;x /= 10;
}

(5)输出时倒序打印(因为低位存在前面)。

// 输出结果(倒序)
for (int i = len; i >= 1; --i)cout << a[i];

按照样例输入对数据进行验证。

image.png

符合样例输出结果。

三、完整代码

该题的完整代码如下:

#include <iostream>
#include <cstring>
using namespace std;int a[40010], n, x, len = 1;int main()
{cin >> n;           // 输入 na[1] = 1;           // 初始结果为 1for (int i = 1; i <= n; ++i) // 从 1 乘到 n{x = 0;           // 每次从无进位开始for (int j = 1; j <= len; ++j){a[j] = a[j] * i + x; // 当前位乘 i 并加上进位x = a[j] / 10;       // 计算新的进位a[j] %= 10;          // 保留个位数字}// 若乘完后还有进位,则继续加位while (x > 0){a[++len] = x % 10;x /= 10;}}// 输出结果(倒序)for (int i = len; i >= 1; --i)cout << a[i];cout << endl;return 0;
}

四、总结

通过本题《求 10000 以内 n 的阶乘》的练习,我们掌握了高精度乘法的完整实现过程
由于阶乘增长极快,即使是 n = 100,结果也已经超过了所有基本整数类型的表示范围,因此需要使用数组模拟大整数运算。

在本题中,我们主要收获了以下几个知识点:

1、 高精度存储思想

使用数组 a[] 按位存储每一位数字(低位在前,高位在后),便于逐位计算和进位操作。

2、模拟竖式乘法运算

对每一位执行 a[j] = a[j] * i + x,再用 /10 求进位、%10 保留个位,实现和手工乘法一致的逻辑。

3、动态控制数组长度

每次乘完后若有新的进位,则继续增加结果长度 len,确保结果完整。

4、倒序输出结果

由于计算时是倒序存储的,输出时需从高位(len)开始依次输出,才能得到正确的阶乘结果。

技巧总结:

高精度乘法是高精度运算的核心,思路与“2 的 N 次方”题相似,但乘数是递增变化的。

注意在每次乘法中清空进位变量 x,否则会影响下一轮计算。

阶乘结果的位数非常多,要根据实际最大 n 值合理预留数组大小。

通过这道题,我们进一步掌握了高精度算法的通用框架,并为解决更复杂的大数加法、乘法、组合数等问题奠定了坚实的基础。

---end---

如果你觉得这篇文章对你有帮助,欢迎点赞、收藏、关注我哦!
如果有更好的方法也可以在评论区评论哦,我都会看哒~

我们下集见~

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

相关文章:

  • 建立公司网站的重点模板之家网页模板下载
  • 做外贸搜索外国客户的网站恢复wordpress修订版本号
  • 合肥网站设计服品牌运营中心
  • ajaxjsp网站开发从入门到精通网站源码文件
  • 导购网站如何做怎么只做自己的电商网站
  • iis搭建本地网站给单位建设网站
  • MATLAB三角模糊层次分析法在高校实验室评估中的应用
  • 杂记 13
  • 女士手表网站网站开发公司oa
  • MySQL非root安装-初始化数据库时unknown variable ‘defaults-file=**/my.cnf‘
  • 【Java】从匿名内部类到函数式接口
  • 小型企业网站建设项目天津百度seo
  • 怎样增加网站流量什么是企业vi设计
  • 广汉移动网站建设微信公众官方平台入口
  • 团购网站开发与设计wordpress有中文吗
  • 青岛网郑州做网站优化公
  • 2025年--Lc181--H331. 验证二叉树的前序序列化(二叉树,计数器)--Java版
  • 快速建设一个网站wordpress页面排序
  • 营销网站制作都选ls15227芜湖中凡网站建设公司
  • 网站程序预装长沙专业竞价优化首选
  • 淄博桓台网站建设报价钢筋网片规格型号
  • 深圳真空共晶炉公司
  • 站长工具里查看的网站描述和关键词都不显示阿里云镜像wordpress
  • 潍坊地区网站制作官方网站的要素
  • 微信小程序一站式开发男女做羞羞羞的网站
  • 咸宁建设网站wordpress发表的文章在页面找不到
  • 松原市城乡建设局网站安阳论坛网
  • 佛山市官网网站建设怎么样建筑设计资料网站
  • 四川网站开发制作做新闻h5网站
  • 验证-SystemVerilog-数据类型、断言