基于AOJ 787和51nod 1057讨论N的阶乘问题。
在这里,讨论的大数阶乘的算法主要是模拟乘法运算,我们用一个乘数和另一个乘数各位相乘,则该乘积的个位为结果的一位,该乘积的高位均为进位。需要注意的是,各位乘完后,进位可能是个多位数,则该多位数可以直接输出。我们可以设置一个数组w[k],来保存乘数和乘积(二者共用)。
模板如下:
while(循环条件)
{
a=w[k]*p+m;
w[k]=a%10;
m=a/10;
}
AOJ787:
C. 阶乘中找数
Time Limit: 1000 ms Case Time Limit: 1000 ms Memory Limit: 64 MB
Total Submission: 16 Submission Accepted: 10
Total Submission: 16 Submission Accepted: 10
Description
问题描述:统计n阶乘中数字p的个数
Input
多组数据,每组数据只有一行,为两个正整数n,p (n<=800,0<=p<=9)
Output
输出为两行,一行为n!, 另一行为n! 中数字p的个数
Sample Input
Original | Transformed |
10 8
Sample Output
Original | Transformed |
3628800 2
AC代码:
#include <stdio.h>
int main()
{
int n,p,a,m,i,j,k,w[2005],s;
while(scanf("%d %d",&n,&p)!=EOF)
{
w[0]=1;
k=0;
for(i=1;i<=n;i++)
{
m=0;
for(j=0;j<=k;j++)
{
a=w[j]*i+m;
w[j]=a%10;
m=a/10;
}
while(m>0)
{
k++;
w[k]=m%10;
m/=10;
}
}
s=0;
for(i=k;i>=0;i--)
{
printf("%d",w[i]);
if(w[i]==p)
s++;
}
printf("\n%d\n",s);
}
return 0;
}
1057 N的阶乘
输入N求N的阶乘的准确值。
Input
输入N(1 <= N <= 10000)
Output
输出N的阶乘
Input示例
5
Output示例
120
该题的n给到了10000,若按照原有方式模拟必然超时,因此需要优化。优化方式是将大数切段存储,具体切成几位一段可随意,题主在AC时切成5位一段。
AC代码:
#include <stdio.h>
int main()
{
int n,p,a,m,i,j,k,w[10005];
while(scanf("%d",&n)!=EOF)
{
w[0]=1;
k=0;
for(i=1;i<=n;i++)
{
m=0;
for(j=0;j<=k;j++)
{
a=w[j]*i+m;
w[j]=a%100000;
m=a/100000;
}
if(m>0)
{
k++;
w[k]=m%100000;
}
}
printf("%d",w[k]);
for(i=k-1;i>=0;i--)
printf("%05d",w[i]);
printf("\n");
}
return 0;
}