阶乘尾部零的个数

试统计正整数n的阶乘n!的尾部连续零的个数。

输入样例
2015
输出
502

算法分析:
由于n的规模比较大,其尾数的个数也会非常多,所以在这里我们可以用一个数组来存储阶乘的的各位数字,a[0]存储个位,a[1]存储十位,依次类推。
(1)首先求出 n! 的总位数(取lg最后不要忘了+1)

         总位数m = lg(2 * 3 * 4 * 5 * .... * n) +1 
                        = lg2 + lg3 +lg4 + lg5 + ...lg n  +1

(2)开两重循环模拟乘法(阶乘)

      (a)然后设置循环进行累乘,将各位数值存入a数组中。i的结果依次为
           2、3、4、5、6、......、n
           
       (b) 设g为进位数, 各个数的乘积 t = a [ j ] * i + g,
      
      (c)乘积t的个位数字存于本数组a [ j ] = t %10
             乘积t的十位以上数字作为进位数g,即余数g = t /10
      
      (d)开设一个while循环计算零的个数

代码

#include<iostream>
#include<cmath>
using namespace std;

const int N = 1e5 + 10;
int n;
int m;
double s;
int a[N]; 
int count = 1;
long g;
 
int main()
{
	cin >> n;
	for(int i = 2; i <= n; i++)
		s += log10(i);
	m=(int)s+1; //计算总位数 
	
	a[1]=1;g=0;
	for(int i = 2; i <= n; i++)
	{
		for(int j=1; j<=m; j++)
		{
			long t=a[j]*i+g; //用第j位乘以下一个阶乘数字 
			a[j]=t%10;  //a[J]只保留乘积的各位数字 
			g=t/10;     //去掉个位数字后当作进位 
		}
	}
	while(a[count]==0)
		count++;
	printf("%d\n",count-1);
}

算法优化
从数学的思想考虑:

例如2015!= 1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * 10 * … * 2014 * 2015
只有所有因子 2 和 5 相乘时,乘积才会出现一个零,又因为因子2的个数远多于因子5的个数,所有阶乘尾部0的个数由因子5的数量决定

问题就转换成 2015 ! 中由多少个因子5.

从上述式子中不难发现每五个数字会出现一个因子5
1 2 3 4 5 -----6 7 8 9 10 即形成了这样的表达形式A
{…5,…10,…15,…20,…2015} 共计2015/5个

以此类推

将A式子提取公因式形成B式
5*{1,2,3,4,5,6,7,8,9,10…}
进而整理成C式
5*{…5,…10,…15,…,20…} 共计2015/(5*5)

代码

#include<iostream>
using namespace std;

long long n;
int count;
long long t = 1;

int main()
{
	cin>>n;
	while(t <= n)
	{
		t = t * 5;
		count = count + n / t;
	}
	cout<<count;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值