本题要求实现一个打印非负整数阶乘的函数。
函数接口定义:
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
第一眼看过去的时候觉得就是一道普普通通的阶乘题目,想着直接就用递归来做,很快就做完了,然后输入测试用例15一看结果根本就不对。然后就想着是不是int的范围太小了,改用long long来写,结果还是不对,然后查找资料发现,当12!的之后就已经超过了long long的范围。在社区寻找答案,就看到大佬们是用数组来进行求。
解题思路
用数组来进行保存每个位置上的数字,然后用乘法运算每个位置的积。
乘法运算法则
比如120×6=
首先我们运算的是个位上的数字0,0*6=0;
然后到2*6=12,这时候我们发现他有两位数字了,但是我们需要的是这个位置的个位数就是,我们就可以把它拆解出来,将2保留到数组之中,1是进位的数字应该跟下一位数字相加的。
最后就1*6了,但是我们不要忘记了,我们上一位中还有一个1在那里,所以我们要把1加上去就是1*6+1=7。然后把7保留到数组之中。
然后我们就可以把数组打印出来即720。
其实到这还没完成,因为到最高位的时候,如果超过10怎么办或者100,即它有两位数以上。所以我们应该把最高位来判断一次,把它分解成一个一个数然后加入到数组中,即while循环。
此时不难发现我们上面求得就是6!,然后就到7!。就是720×7,以此类推,我们就可以一直推到1000,我们还需要注意就是数组要定义大一点,不然就会出现段错误。
void Print_Factorial(const int N)
{
int i,k=0;
int sum=1;
int carry=0,temp = 0;
int a[5000];
if(N>=0&&N<=12)
{
for (i = 1; i <= N;i++)
{
sum = sum * i;
}
printf("%d", sum);
}
else if(N>12&&N<=1000)
{
a[0] = 1;
for (int i = 2; i <= N;i++)
{
for (int j = 0; j <= k;j++)
{
temp = a[j] * i + carry;
a[j] = temp % 10;
carry = temp / 10;
}
while(carry)
{
a[++k] = carry%10;
carry = carry / 10;
}
}
for (i = k; i >= 0;i--)
{
printf("%d", a[i]);
}
}
else
printf("Invalid input");
}