求一个阶乘最后面一个非零数
Description
N的阶乘写作N!表示小于等于N的所有正整数的乘积。阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了。你的任务是找到阶乘最后面的非零位。举个例子,5!=12345=120所以5!的最后面的非零位是2,7!=1234567=5040,所以最后面的非零位是4。
Input
共一行,一个整数不大于4,220的整数N。
Output
共一行,输出N!最后面的非零位。
Sample Input
7
Sample Output
4
老师讲了两种思路,第一种思路很简单,第二种思路稍微复杂
思路一:循环从1到n连续相乘,每次乘完后判断去除后面的0。避免数据过大,要对10000取余。
#include<stdio.h>
int main()
{
int n,i,chengji=1;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
chengji*=i;
while(chengji%10==0)
chengji/=10;
chengji%=10000;
}
printf("%d\n",chengji%10);
return 0;
}
思路二:寻找阶乘里面有多少个5,然后再从阶乘里消去同等数量的2,这样就直接消去了所有的10,再把剩下的相乘即可。
#include<stdio.h>
int main()
{
int n,i,j,chengji=1;
int dat[5000],cnt=0;
scanf("%d",&n);
for(i=n;i>=1;i--)//计算5的个数
{
dat[i]=i;
while(dat[i]%5==0)
{
dat[i]/=5;//dat数组中存的都是不为5的倍数的数
cnt++;//cnt统计5的个数
}
}
for(i=n;i>=1;i--)//去掉与5一样多得2
{
if(cnt==0)//数中都不带5
break;
while(dat[i]%2==0&&cnt!=0)//cnt中存的是5的个数 除以一次2就cnt--,要确保吾的个数与二的个数相同
{
dat[i]/=2;
cnt--;
}
}
for(i=n;i>=1;i--)//无需处理0的问题 每次5*2=10都没有算进来,不影响计算
{
chengji*=dat[i];
chengji%=10000;
}
printf("%d\n",chengji%10);
return 0;
}
我是菜鸡 我是菜鸡 我是菜鸡