本题要求实现一个打印非负整数阶乘的函数。
函数接口定义:
void Print_Factorial ( const int N );
其中 N 是用户传入的参数,其值不超过 1000。如果 N 是非负整数,则该函数必须在一行中打印出 N! 的值,否则打印 “Invalid input”。
裁判测试程序样例:
#include <stdio.h>
void Print_Factorial ( const int N );
int main()
{
int N;
scanf("%d", &N);
Print_Factorial(N);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
15
输出样例:
1307674368000
来源:
来源:PTA | 程序设计类实验辅助教学平台
链接:https://pintia.cn/problem-sets/14/exam/problems/742
提交:
题解:
/*
* 实现一个打印非负整数阶乘的函数,其中 N 是用户传入的参数,其值不超过 1000。
* 如果 N 是非负整数,则该函数必须在一行中打印出 N! 的值,否则打印 “Invalid input”
*/
void Print_Factorial(const int N) {
// 负数没有阶乘
if (N < 0) {
printf("Invalid input");
return;
}
/*
* 大数阶乘问题(模拟乘法):用户输入的 N 最大为 1000,1000! 有 2568 位数,超过 C 语言数据类型范围,故使用整型数组 result[3000] 记录阶乘结果
*/
// max 为最大数组下标,即 3000 - 1
int max = 2999;
// cur 为当前数组下标
int cur = max;
// 初始化结果数组最后一位为 1,其余位为 0
int result[3000] = {0};
result[max] = 1;
// 模拟乘法计算 N!,外循环控制从 2 乘到 N,因为 0 和 1 的阶乘为 1,已在 result 结果数组中初始化
for (int num = 2; num <= N; num++) {
// 是否产生进位:[0]未进位 [1]进位
int flag = 0;
// 进位值
int carry = 0;
// 模拟乘法:内循环使用当前数字 num 从右往左依次乘以结果数组 result 的每一位,有效范围为 [cur, max]
for (int i = max; i >= cur; i--) {
// 当前位的值
result[i] = result[i] * num + carry;
// 进位值存在且在已使用,重新赋值为 0
if (flag) {
carry = 0;
}
// 判断当前位是否需要进位
if (result[i] > 9) {
// 进位值存在则 flag 为 1
flag = 1;
// 向前的进位值
carry = result[i] / 10;
// 进位后当前位的值
result[i] %= 10;
// num 已乘到第 cur 位,但此处仍产生进位,则 cur-- 以向前进位
if (i == cur) {
cur--;
}
}
}
}
// 由高位向低位输出 N! 结果
for (int i = cur; i <= max; i++) {
printf("%d", result[i]);
}
}