题目:
函数printFactorial(int n)的功能是输出非负整数n的阶乘,n的值不超过1000,对于不满足输入要求的n值,输出“Invalid input”,否则在一行上输出n!。
裁判服务器中的测试程序及样例如下:
#include <stdio.h>
void printFactorial(int n);
int main()
{
int n;
scanf("%d", &n);
printFactorial(n);
return 0;
}
/* 你提交的函数定义将放在此位置 */
输入样例:
15
输出样例:
1307674368000
此题看似简单,却暗藏玄机,因为无论是long int 还是long long int 类型都不能储存接近于1000的正整数的阶乘,所以我们要自定义算法来输出大数。下面是程序及具体解释:
#include <stdio.h>
#define MAX 5000//定义位数的最大值为5000(1000阶乘的最大值也没有超过5000)
void printFactorial(int n){
int res[MAX];
int res_size = 1;//初始化位数为1
res[0] = 1;
if(n > 1000 || n < 0){
printf("Invalid input");//排除n>1000或者 n<0的情况
return;
}
else if(n == 0){
printf("1\n");//由定义知0的阶乘为1
}
else {
for (int i = 2; i <= n; i++) {//从2开始,乘以res数组中储存的当前阶乘结果,直到n
int carry = 0;
for(int j = 0; j < res_size; j++){//遍历res数组,执行乘法并处理进位
int prod = res[j] * i + carry;
res[j] = prod % 10;
carry = prod / 10;
}///乘法从 res 的最低位开始,处理每一位乘以 i 并加上进位 carry,
///更新 res[j] 为乘积的个位数,并计算新的进位(乘积除以 10 的商)
while(carry){
res[res_size] = carry % 10;//res[1]=2,res[2]=1,
carry = carry / 10;//carry=0,carry=0,
res_size++;//res_size=2,
}///处理完 res 中的所有位后,如果仍有进位(carry 不为零),
///则将进位添加到 res 的下一个位置,并增加数组的有效长度 res_size。
}
for(int i = res_size - 1; i >= 0; i--){
printf("%d",res[i]);
}///计算完毕后,从 res 数组的末尾(即最高位)开始逆序打印每一位数字,这样就得到了最终的阶乘结果。
printf("\n");
}
}
int main() {
int n;
scanf("%d", &n);
printFactorial(n);
}
这样问题就解决了。