统计N!末位0的数量的一个思路

来源:互联网 发布:软件开发职位 编辑:程序博客网 时间:2024/05/21 21:48

问题描述如下:

1008. Zero

Time limit per test: 2.0 seconds

Memory limit: 256 megabytes

A long time ago people found the value zero to be very useful. Just think about the romans and many more nations that didn't know the zero. Their number representations couldn't display the zero and that's why they are dead now.

So you've got to understand the overwhelming importance of this beautiful gift of science (or nature ?) and praise the zero. That's what you'll do here.

Find out how many trailing zeros are at the end of n! (n factorial). That's all you have to do, but be careful to write an efficient program, n can be really large. For example,

42! = 1405006117752879898543142606244511569936384000000000

so the answer for n=42 would be 9, since there are nine zeros at the end.

Input

The first line contains an integer m, the number of test cases. After that follow m lines. Every line represents one testcase, which only contains the integer number n. The value of n will be at least 1 and won't be bigger than 2.000.000.000.

Output

For each testcase, print a line containing the number of trailing zeros. Do not print whitespace before or after the number.

Examples

input
4123422000000000
output
049499999997
问题规模N最大可达20亿,用暴力的方法做显然是不可取的。

博主给出一个解决思路,如下:


//末位的0来自于因子10,每个因子10有来自于素因子2和5
//通过简单的证明发现,素因子2的数量必然多于5
//于是仅需要统计素因子5的数量
/*
5+1
10+1
15+1
20+1
25+2//每25额外+1
30+1
35+1
40+1
45+1
50+2//每25额外+1
......
120+1
125+3//每25额外+1//每125额外再+1
......
*/



于是我们就把问题转化为:统计由1到N所有数的素因子5的数量

通过反复mod5的效率太低,简单的估算就发现已经超过了时间限制。

下面以N=42的情况为例

通过观察,不难发现,42!的对应output是9

来自于5,10,15,20,25,30,35,40的8个5,以及25的额外一个5

所以博主想了一个做法,就是42以内5的倍数的数量加上25的倍数的数量,以此类推直到5的某次幂超过42为止

计算部分用c++实现如下

int counter5(long long num)
{
int ct5 = 0;
int division = 1;


long long T = pow(5, division);
for (; num / T != 0; division++)
{
ct5 += (num / T);
T = pow(5, division + 1);
}
return ct5;
}

时间复杂度应该为O(logN)

也许还存在更好的做法,但博主还没有想得到。如果你有更好的做法,请不吝赐教。



解决整个问题的c++代码实现如下


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


int counter5(long long num);


int main()
{
long long c5 = 0;


long long N;
int i = 0, T;
cin >> T;
while (i < T)
{
cin >> N;
c5 = counter5(N);
cout << c5 << endl;
i++;
}
return 0;
}




int counter5(long long num)
{
int ct5 = 0;
int division = 1;


long long T = pow(5, division);
for (; num / T != 0; division++)
{
ct5 += (num / T);
T = pow(5, division + 1);
}
return ct5;
}



原创粉丝点击