阶乘是个很有意思的函数,我们来看看两个跟阶乘相关的问题。
1、给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N! = 3628800,末尾就有两个0
2、求N! 的二进制表示中最低位1的位置
 
我们先分析第一个问题
我们发现0的个数,就是10的个数,而10是由2跟5组成的,但是,5的个数明显少于2,所以问题就转换为求5的个数。
 1 #include <iostream>
 2 using namespace std;
 3 // O(nlogn),思路:找0的个数,就是找10的个数,就是2*5的个数,2比5多,所以就是找5的个数,首先找到5的倍数,再判断这些数里面有多少个5
 4 int numOfZeros1(int n)
 5 {
 6     //i从1开始,当n为26时,那么i就是1,2,3,4,5
 7     //j就是5*i,所以对于的j就是5,10,15,20,25,第二个while循环找的就是j中有多少个5,像数字25,就有2个5
 8     //count表示的5的个数,即0的个数
 9     int i, j, count;
10     i = 1;
11     count = 0;
12     while (5 * i <= n)
13     {
14         j = 5 * i;
15         while (j % 5 == 0)
16         {
17             count++;
18             j = j / 5;
19         }
20         i++;
21     }
22     return count;
23 }
24 // o(logn),从时间复杂度上来说,优化的多。思路:n=26时,0的个数就是[26/25]+[26/5]=1+5=6
25 int numOfZeros2(int n)
26 {
27     int i, count;
28     i = 0;
29     count = 0;
30     while (n / 5)
31     {
32         count += n / 5;
33         n /= 5;
34     }
35     return count;
36 }
37 int main()
38 {
39     int n;
40     n = 125;
41     //test
42     cout<<numOfZeros1(n)<<endl;
43     cout<<numOfZeros2(n)<<endl;
44     system("pause");
45     return 0;
46 }

 

第二个问题的解答如下,分析也在代码中了

 1 #include <iostream>
 2 using namespace std;
 3 // o(logn),在二进制中,乘以2就表示多一个0,所以,1最低位的位置其实就是2个个数+1
 4 int indexOfOne(int n)
 5 {
 6     int i, count;
 7     i = 0;
 8     count = 0;
 9     //这里进行了一点点调整,更简洁了,可对比上面的代码,看看哪里调整了
10     while (n)
11     {
12         //注意除以2,都可以用右移来标识哦!!
13         n = n >> 1;
14         count += n;
15     }
16     return count + 1;
17 }
18 int main()
19 {
20     int n;
21     n = 3;
22     //test
23     cout<<indexOfOne(n)<<endl;
24     system("pause");
25     return 0;
26 }

 

posted on 2014-05-02 10:56  MrMission  阅读(170)  评论(0编辑  收藏  举报