首页 > 代码库 > POJ1401-Factorial
POJ1401-Factorial
Description
ACM technicians faced a very interesting problem recently. Given a set of BTSes to visit, they needed to find the shortest path to visit all of the given points and return back to the central company building. Programmers have spent several months studying this problem but with no results. They were unable to find the solution fast enough. After a long time, one of the programmers found this problem in a conference article. Unfortunately, he found that the problem is so called "Travelling Salesman Problem" and it is very hard to solve. If we have N BTSes to be visited, we can visit them in any order, giving us N! possibilities to examine. The function expressing that number is called factorial and can be computed as a product 1.2.3.4....N. The number is very high even for a relatively small N.
The programmers understood they had no chance to solve the problem. But because they have already received the research grant from the government, they needed to continue with their studies and produce at least some results. So they started to study behaviour of the factorial function.
For example, they defined the function Z. For any positive integer N, Z(N) is the number of zeros at the end of the decimal form of number N!. They noticed that this function never decreases. If we have two numbers N1 < N2, then Z(N1) <= Z(N2). It is because we can never "lose" any trailing zero by multiplying by any positive number. We can only get new and new zeros. The function Z is very interesting, so we need a computer program that can determine its value efficiently.
Input
Output
Sample Input
63601001024234568735373
Sample Output
0142425358612183837
//逢一个因子5会产生一个0,
//如10!=10*9*8*7*6*5*4*3*2*1中有两个因数5,能构成结尾2个0。
//数论:这道题的正解就是对sum=n/5+n/25+n/125......n/(5^k),直到n<(5^k).复杂度是log5(N)
具体解释:
首先通过将n分解因式,我们知道上述充分性是成立的,因为所有末尾的0都可以看成因子10,而10可以分解为2*5,所以末尾的一个0必然对应这一个5。而每个0也必然来自一个因子5。那么有个问题,就是n!中是否有足够的2把所有的5都变成10呢?答案是肯定的:对于任意n!>=5,有n = (5*10*15*......*5(k-1)*5k)*a,其中a是不能被5整除的整数。那么对于上述序列5,10,15,......,5(k-1),5k中的每一个5,在区间(5(i-1),5i]中必存在一个偶数,这个偶数中的2就可以把这个5变成结尾的0了。//如果你还不好理解的话,就把数轴分别以5和2分割,那么是不是清晰了呢!
所以,对于n!中任意一个因子5,对应着一个末尾0,那么我们只要求出n!中有多少个因子5,就知道它末尾有多少个0了。
假设n!中有f(n!)个5,那么有f(n!) = (n!/5) + f(n!/5);所以就可以用递归的方法求解n!中5的个数了。
代码如下:
#include <cstdio>
int main(){
int i , t , s ;
long long n ;
scanf("%d",&t);
while(t--){
scanf("%lld",&n);
s = 0 ;
while(n / 5){
s+=n / 5 ;
n/= 5 ;
}
printf("%d\n",s);
}
}
POJ1401-Factorial