阶乘之乘

题目描述

求出1!*2!*3!*4!*……*n!的末尾有几个零

输入格式

n(n<=10^8)

输出格式

有几个零

样例输入

10

样例输出

7

思路

这题相对来说很简单,但是看到数据范围我蒙圈了,10^8,要在这个范围内阶乘,10^4估计已经撑不住了,所以我们要增加很多优化,第一个优化就是在处理阶乘时的优化,我们可以把复杂度为O(n^2)的二重循环改为复杂度为O(n)的复杂度。

优化前

for(int i=1;i<=n;i++)
{
    int t=1;
    for(int j=1;j<=i;j++)
    {
        t*=i;
    }
    ans*=t;
}

优化后

for(int i=1;i<=n;i++)
{
    t*=i;
    ans*=t;
}

接着就是如何找到数字末尾有几个零,我们可以利用while循环来找。

具体如下

while(ans%10==0){
    cnt++;
    ans/=10;
}

最后输出就行了

上代码

你以为就完了你就错了

因为while循环中过大会爆,所以我们可以求2和5的个数(把10分为2和5),这样程序就优化的差不多了,看看下面。(可以优化,不需要2了,代码为最终优化结果)

while(t%5==0)
{
	sum5++;
	t/=5;
}
ans5+=sum5;

现在没问题了,上代码

#include <bits/stdc++.h>
using namespace std;

int main(){
	long long n,cnt,sum5=0,ans5=0;
	cin >>n;
	for(int i=1;i<=n;i++){
		int t=i;
		while(t%5==0)
		{
			sum5++;
			t/=5;
		}
		ans5+=sum5;
	}
	cout <<ans5;
    return 0;
}

代码虽然不长,但可以学到很多的优化知识和思想。

点个赞再走吧 😏

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值