POJ 1401 Factorial 试着分析一下数学问题

【简单题,试着分析一下,发现自己表达能力不够好哈】

题意:给一个数N,计算N!末尾有几个0。

因为这道题出现在动态规划的作业中,一开始也尝试着去DP了下。结果案例总是通不过。DP功力还不够。

看来,还要用做数学题的办法试试。

如果使末尾多一个0,那么这个可以由2 * 5得到;

如果末尾多两个0,可以由4 * 25得到;

推广:

末尾0的个数    等式    等式左边    等式右边

  1       2 * 5     2^1     5^1

  2       4 * 25     2^2       5^2

  3       8 * 125     2^3     5^3

  ...        ...       ...      ...

  n                2^n     5^n

又发现,对一个数N,定义s(x)表示x!末尾0的个数

所以s(N!) = (N / 5^1) + (N / 5^2) + (N / 5^3) + ...

优化:

当5^i > N时,商为0。当循环进行到5^i > N时,就可以终止了。

又给出数据最大为10^9,log(5^13) > 9。所以对于每个数最多只需计算12次。

得到算法。

 

代码:

 1 #include <iostream>
2 using namespace std;
3
4 int num[15];
5
6 void init()
7 {
8 num[0] = 1;
9 for(int i = 1; i <= 13; i++)
10 num[i] = num[i-1] * 5;
11 }
12
13 int main()
14 {
15 int t;
16 init();
17 scanf("%d", &t);
18 while (t--)
19 {
20 int n, total = 0;
21 scanf("%d", &n);
22 for(int i = 1; i < 14 && num[i] <= n; i++)
23 total += n / num[i];
24 printf("%d\n", total);
25 }
26 return 0;
27 }

 

posted @ 2012-03-12 22:51  dgsrz  阅读(155)  评论(0编辑  收藏  举报