本题要求实现一个打印非负整数阶乘的函数。
函数接口定义:
void Print_Factorial ( const int N );
其中N是用户传入的参数,其值不超过1000。如果N是非负整数,则该函数必须在一行中打印出N!的值,否则打印“Invalid input”。
裁判测试程序样例:
void Print_Factorial ( const int N );
int main()
{
int N;
scanf("%d", &N);
Print_Factorial(N);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
15
输出样例:
1307674368000
解题思路
最后的结果最大有两千多位,只能开辟数组来存放结果。
实现代码
void Print_Factorial(const int N)
{
int ans[3000]= {0}; //用来存放答案的数组
int n=0; //进位标识
int num=1; //标记当前结果即数组的位数
int temp; //当前位与循环值相乘的结果
if(N<0)
printf("Invalid input\n");
else
{
ans[0]=1;
for(int i=2; i<=N; i++)
{
for(int j=0; j<num; j++)
{
temp=ans[j]*i+n;
ans[j]=temp%10;
n=temp/10;
}
while(n!=0)
{
ans[num]=n%10;
n/=10;
num++;
}
}
for(int i=num-1; i>=0; i--)
printf("%d",ans[i]);
printf("\n");
}
}
思路小结
该题有些类似于大数乘法,不同的是相乘的数字还在整型的范围内。然后借地整理一下大数乘法的基本模板。
模板代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stdlib.h>
#include<cmath>
using namespace std;
void exchange(char *str,int p,int q) //将数字字符串实现逆序
{
char temp;
while(p<q)
{
temp=str[p];
str[p]=str[q];
str[q]=temp;
p++,q--;
}
}
char *multi(char *A,char *B)
{
int m=strlen(A);
int n=strlen(B);
char *result=new char[m+n+1]; //开辟新的存放结果的数组
memset(result,'0',m+n);
result[m+n]='\0';
exchange(A,0,m-1); //将A,B字符串逆序
exchange(B,0,n-1);
int multiflag,addflag,i,j; //依次为乘法进位标志与加法进位标志
for(i=0;i<n;i++)
{
multiflag=0,addflag=0;
for(j=0;j<m;j++)
{
int temp1=(A[i]-'0')*(B[j]-'0')+multiflag;
multiflag=temp1/10;
temp1%=10;
int temp2=(result[i+j]-'0')+temp1+addflag;
addflag=temp2/10;
result[i+j]=temp2%10+'0';
}
result[i+m]+=multiflag+addflag;
}
exchange(result,0,m+n-1); //将结果字符串逆序使得结果为正序
return result;
}
int main()
{
char A[]="99999999999";
char B[]="99999999999";
char *res=multi(A,B);
if(res[0]!='0')
printf("%c",res[0]);
printf("%s",res+1);
return 0;
}