一些PTA题目经验总结 (1)
6-10 阶乘计算升级版
- 题目要求
- 本题要求实现一个打印非负整数阶乘的函数。
- 函数接口定义:
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
- 输入样例:
思路
难点
这题和之前普通阶乘计算不一样的地方,就是计算的得到的数十分大。C语言里无论哪个数据类型都没法容纳,于是会出现计算错误。
所以这里需要防止阶乘计算时,得出的数太大。
解决方法
为了防止数太大,就将数的每一位拆开,用一个数组储存每一位的数字,然后按照一定规律运算即可。
步骤
- 计算
- 将每一位与n相乘
- 将数拆开
- 数字超过一位,剪切前面的几位,只留最后一位
- 将剪切的位数加到前面一位
- 重复上面两个操作直到每一位都只有一个数
- 重复上面步骤,直到相乘的数为N
- 输出得到的数
原理
我们平常计算乘法的时候,就是以单个数乘法来算的,将乘数的每一位与被乘数相乘,然后相加,才计算出来
例子
123*12
123 //乘数与被乘数每一位相乘
12
-----------
246 //相加
+ 1230
-----------
1476 //结果
代码
void Print_Factorial(const int N){
if(N < 0){
printf("Invalid input"); //特殊情况
}else if(N > 1000){
printf("Invalid input");
}else if(N == 0){
printf("1");
}else{
int a[4096];
int temp, digits, n1, i, j;
a[0] = 1;
digits = 1;
n1 = 0;
for(i = 1; i <= N; i++){ //进位
for(j = 0; j < digits; j++){
temp = a[j] * i + n1;
a[j] = temp % 10;
n1 = temp / 10;
}
while(n1 != 0){
a[digits] = n1 % 10;
n1 /= 10;
digits++;
}
}
for(i = digits - 1; i >= 0; i--){ //倒过来输出
printf("%d",a[i]);
}
}
}