ZCMU—1375
2017-01-01 23:09
225 查看
1375: 阶乘的零
Time Limit: 1 Sec Memory Limit: 128 MB[Submit][Status][Web
Board]
Description
定义f(n)为n!的末尾零的个数,例如f(4)=0,f(5)=1。你的任务是对于一个给定的的值x找出最小的n满足f(n)=x。Input
多组测试数据,每组测试数据包含一个正整数x(1<=x<=10^8)。Output
对于每组测试数据输出对应的n,若没有n满足则输出“No solution”。Sample Input
2Sample Output
10HINT
water problem!【分析】
首先...我们要会算n!有几个0,显然有几个0取决于n!这个数中因子2的个数和因子5的个数,显然2的个数远大于5,所以只要考虑因子5的个数就可以了~当然不能用n的算法...需要log5(n)的速度...对N进行质因数分解 N=2^x * 3^y * 5^z...,由于10 = 2*5,所以末尾0的个数只和x与z有关,每一对2和5相乘可以得到一个10,于是末尾0的个数=min(x,z)。在实际中x是远远大于z的,所以我们只要求出z的值即可。
根据公式
z = N/5 + N/5^2 + N/5^3+...+N/5^k
这表明,5的倍数贡献了一个5,5^2的倍数又贡献了一个5...
比如:25其实是贡献了2个5,但是在N/5中已经贡献了一个,所以在N/5^2中再贡献一个;同样,125在N/5中贡献一个,在N/5^2中贡献一个,在N/5^3中再贡献一个,一共是3个。
知道这点之后就容易了,这道题显然是有数学公式可以直接求答案的...但是因为我比较懒所以写了个二分直接查答案了...因为上面这个算n!末尾0个数的速度太快了,加上二分基本上也属于常数算法...所以....嗯直接搜吧!手动给一个极大的区间然后搜就好了
【代码】
#include <stdio.h> long long find(long long x) { long long ans=0; while (x) { ans+=x/5; x/=5; } return ans; } int main() { long long n; while (~scanf("%lld",&n)) { long long left=5; long long right=1000000000000; while (left<right) { long long mid=(left+right)/2; long long m=find(mid); if (m==n) { while (mid%5) mid--; printf("%lld\n",mid); goto out; } if (m>n) right=mid-1;else left=mid+1; } printf("No solution\n"); out:; } }
相关文章推荐
- LightOJ 1375 LCM Extreme(最小公倍数和)
- Light OJ 1375 LCM Extreme 欧拉函数 (或 莫比乌斯反演 ?)
- 【日常学习】【高精】【数学递推】tyvj1375 山洞历险题解
- poj1375 圆的切线
- ZCMU1692 鬼吹灯
- ZCMU—1758
- ZCMU—1431
- ZCMU—1177
- ZCMU—1728
- ZCMU-1755-数字整除
- ZCMU-1155-春运
- ZCMU-1305-第K完美序列
- ZCMU—1551
- ZCMU-1343-素数对
- ZCMU-1180(大数相乘)
- ZCMU-1720-死亡如风,我要装逼
- ZCMU-1607-大二下之悬梁刺股
- ZCMU-1841-完美的代价
- ZCMU-1863-zbj的长跑
- poj2550&&zcmu1867——Zipf's Law