当前位置:首页 > 技术 > 正文内容

大数阶乘的高效计算方法

访客 技术 2026年8月23日 2

题目链接:nyoj 28

这是一个关于高精度计算的问题,解决大数阶乘的挑战。最初我尝试使用预计算表的方法,但内存超出了题目限制(5w+kb)。通过多种优化技巧,成功将内存消耗降低到要求范围内,以下是我的实现代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 using namespace std;
 6 typedef long long LL;
 7 const int MAX_N = 5002;
 8 const int MOD = 1e6;
 9 
10 int result[MAX_N + 3][2800], digit_count[MAX_N + 3];
11 
12 inline void initialize(int limit = MAX_N) {
13     result[1][0] = 1;    digit_count[1] = 1;
14     for(int i = 2; i <= limit; ++i) {
15         int current_length = digit_count[i - 1];
16         int carry = 0;
17         LL temp;
18         for(int j = 0; j < current_length; ++j) {
19             temp = carry + (LL)result[i - 1][j] * i;
20             result[i][j] = temp % MOD;
21             carry = temp / MOD;
22         }
23         while(carry) {
24             result[i][current_length++] = carry % MOD;
25             carry /= MOD;
26         }
27         digit_count[i] = current_length;
28     }
29 }
30 
31 inline void display_digits(int num) {
32     putchar(num / 100000 % 10 + '0');
33     putchar(num / 10000 % 10 + '0');
34     putchar(num / 1000 % 10 + '0');
35     putchar(num / 100 % 10 + '0');
36     putchar(num / 10 % 10 + '0');
37     putchar(num % 10 + '0');
38 }
39 
40 inline void print_result(int n) {
41     int index = digit_count[n] - 1;
42     const int &first_num = result[n][index];
43     printf("%d",first_num);
44 
45     for(--index; index >= 0; --index)
46         display_digits(result[n][index]);
47     puts("");
48 }
49 
50 int main() {
51     int test_case;
52     initialize();
53     while(~scanf("%d",&test_case))
54         print_result(test_case);
55     return 0;
56 }

出题者的本意可能是希望我们每次读入一个数后实时计算阶乘,而不是预计算所有结果:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<cctype>
 5 const int MAX_SIZE = 5002;
 6 
 7 int storage[2][18000];
 8 
 9 inline void compute_factorial(int n) {
10     storage[1][0] = 1;
11     int length = 1;
12     for(int i = 2; i <= n; ++i) {
13         int carry = 0, temp;
14         for(int j = 0; j < length; ++j) {
15             temp = carry + storage[!(i & 1)][j] * i;
16             storage[i & 1][j] = temp % 10;
17             carry = temp / 10;
18         }
19         while(carry) {
20             storage[i & 1][length++] = carry % 10;
21             carry /= 10;
22         }
23     }
24     for(int j = length - 1; j >= 0; --j)
25         putchar(storage[n & 1][j] + '0');
26     puts("");
27 }
28 
29 template <typename T>
30 inline bool read_input(T &x) {
31     x = 0;
32     char ch = getchar();
33     while(!isdigit(ch) && ch != EOF)    ch = getchar();
34     if(ch == EOF)   return 0;
35     while(isdigit(ch)) {
36         x = x * 10 + (ch - '0');
37         ch = getchar();
38     }
39     return 1;
40 }
41 
42 int main() {
43     int input_value;
44     while(read_input(input_value))
45         compute_factorial(input_value);
46     return 0;
47 }

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。