ACM程序设计选修课——1024: 末位零(求末尾0的方法+可有可无的快速幂)

1024: 末位零

Time Limit: 1 Sec  Memory Limit: 32 MB
Submit: 60  Solved: 11
[ Submit][ Status][ Web Board]

Description

给定一个正整数N,那么N的阶乘N!末尾有多少个0呢?例如:N10N!=3 628 800N!的末尾有两个0。 

注意:N<=100,000,000

Input

第一行为N,表示有N个输入。接下来有N行,每一行包括一个正整数。

Output

对于每个输入,每行输出结果

Sample Input

2
5
10

Sample Output

1
2

求N的阶乘的末尾几个0,刚开始只知道出现2与5就会有0,后来百度一下发现只要是5的倍数均会+1,贴上原帖思路:

把从 1000 到 1 这些所有的数,只要是5的倍数的,一律分解成含因子5为止。

例如 
10 = 2 * 5 

15 = 3 * 5 

25 = 5 * 5

50 = 2 * 25 = 2 * 5 * 5

100 = 4 * 25 = 4 * 5 * 5

105 = 21 * 5

125 = 5 * 5 * 5 余此类推。
从1 到1000,能被5 整除的数有 1000/5 = 200 个 能被5的平方即25整除的数有 1000/25 = 40 个 能被5的立方即125整除的数有 1000/125 = 8 个
能被5的4次方即625 整除的数有 1000/625 = 1个 (即625自己) 
把这1000个数,只要能分解出因子5,就一直分解到因子5为止。共可分解出  200 + 40 + 8 + 1 = 249  即最终可分解出 249 个5。 
只要有1个5,与偶数相乘后就会出现1个0。 而 从1 到1000,偶数的数量是足够的,所以 有249个5,乘积结果中就有249个0。

由于数据比较大到10^8用longlong,又可以用到可爱的快速幂了,13次方显然没卵用- -|||.

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>
#include<set>
#include<map>
#include<sstream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
inline long long POW5(int b)
{
	long long r=1,bas=5;
	while (b!=0)//蛋疼b写成rWA了一次
	{
		if(b&1)
			r*=bas;
		bas*=bas;
		b>>=1;
	}
	return r;
}
int main (void)
{
	long long n,temp;
	int t;
	scanf("%d",&t);
	while (t--)
	{
		scanf("%lld",&n);
		long long ans=0;
		for (int i=1; i<13; i++)//5的13次我用计算器算了一下大于10^8次了,直接到这够了
		{
			temp=POW5(i);//调试方便查看
			ans=ans+n/temp;
		}
		cout<<ans<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值