• 2.2 编程之美--不要被阶乘吓到[zero count of N factorial]


    [本文链接]

    http://www.cnblogs.com/hellogiser/p/zero-count-of-N-factorial.html

    【题目】

    问题1:‍给定一个整数N,那么N的阶乘N!末尾有多少个0呢?例如:N=10,N!=3 628 800,N!的末尾有两个0。

      思路:这个主要是判断各个数字中5的个数,因为5和偶数相乘以后可以得到10,相当于在后面添加一个0。

    问题2:求N!的二进制表示中最低位1的位置。

      思路:乍一看,似乎,问题二与问题一没什么关系。然而,我们换一个角度思考,二进制中最低位1后面肯定是0,那么这里求最低位1的位置,即为求最低位1后面0的个数,而这,就和问题1是一样的,只不过一个是十进制表,一个是二进制表示。这里,所有小于N的数中,2的倍数都贡献一个0,4的倍数再贡献一个0,以此类推。由于二进制表示其实是以2为基的表示,每出现一个2,末尾才会有一个0,所以只要找到N!中因子2的个数即可。

    【代码】

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/7/8
    */


    //-----------------------------------------------
    // 1 求N! 末尾有多少个0?
    //-----------------------------------------------

    /* 解法一 计算i(i = 1,2,3..N)的因式分解中5的指数 */
    int count(int n)
    {
        
    int ret = 0;
        
    int i, j;

        
    for (i = 1; i <= N; i++)
        {
            j = i;
            
    while (0 == j % 5)
            {
                ret++;
                j /= 
    5;
            }
        }

        
    return ret;
    }

    /* 解法一 优化循环,循环step设置为5 */
    int count(int n)
    {
        
    int ret = 0;
        
    int i, j;

        
    // 循环step设置为5
        for (i = 5; i <= N; i = i + 5)
        {
            j = i;
            
    while (0 == j % 5)
            {
                ret++;
                j /= 
    5;
            }
        }

        
    return ret;
    }

    /* 解法二 z = [N/5] + [N/(5*5)] + [N/(5*5*5)].... */
    /* [N/5]为N中5的个数,[N/(5*5)]为[N/5]中5的个数 */
    /* Z为N!中含有质数5的个数 */
    int  count(int n)
    {
        
    int ret = 0;

        
    while (n)
        {
            ret += N / 
    5;
            N /= 
    5;
        }

        
    return ret;
    }

    //-----------------------------------------------
    // 2 求N!的二进制表示中最低位1的位置
    //-----------------------------------------------

    /* 2=(10),每出现一个2,1前进1位,如二进制 10*10*10*10 = (10000) */
    /* 等于N! 中含有质数因子2的个数加1 */
    /* z = [N/2] + [N/(2*2)] + [N/(2*2*2)].... */
    int lastone(int n)
    {
        
    int ret = 0;
        
    while (n)
        {
        ret += n/2;
            n = n/2;
        }

        
    return ret;
    }

    /* 相关题目 判断n是否为2的方幂 */
    bool is2n(int n)
    {
        
    return n > 0 && ( 0 == (n & (n - 1)));
    }

    [代码2]

     C++ Code 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
     
    /*
        version: 1.0
        author: hellogiser
        blog: http://www.cnblogs.com/hellogiser
        date: 2014/9/18
    */


    // number of zeros of n!
    int num_zeros(int n)
    {
        
    // n = 16
        // 5 10 15 20 25
        // 25
        if(n <= 0)
            
    return -1;
        
    int count = 0;
        
    while(n)
        {
            count += n / 
    5;
            n = n / 
    5;
        }
        
    return count;
    }

    int num_zeros2(int n)
    {
        
    // n = 16
        // 5 10 15 20 25
        // 25
        if(n <= 0)
            
    return -1;
        
    int count = 0;
        
    for (int i = 5; n / i > 0; i = i * 5)
            count += n / i;
        
    return count;
    }


    // pos of last one of n! in bit representation
    int last_one(int n)
    {
        
    if(n <= 0)
            
    return -1;
        
    int count = 0;
        
    while(n)
        {
            count += n / 
    2;
            n = n / 
    2;
        }
        
    return count;
    }

    int last_one2(int n)
    {
        
    if(n <= 0)
            
    return -1;
        
    int count = 0;
        
    for (int i = 2; n / i > 0; i = i * 2)
            count += n / i;
        
    return count;
    }

    【参考】

    http://blog.csdn.net/eric43/article/details/7570474

    http://blog.csdn.net/zcsylj/article/details/6393308

    [本文链接]

    http://www.cnblogs.com/hellogiser/p/zero-count-of-N-factorial.html

    个人学习笔记,欢迎拍砖!---by hellogiser

    Author: hellogiser
    Warning: 本文版权归作者和博客园共有,欢迎转载,但请保留此段声明,且在文章页面明显位置给出原文连接。Thanks!
    Me: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    虚拟机配置桥接网络以及使用mobaxterm连接虚拟机
    maven依赖包问题2
    47.火狐浏览器登录过全球服务器之后,切换回本地服务器登录失败解决方法
    博客园美化
    vue拼图验证(vue-puzzle-vcode)
    vue使用axios
    vue中使用swiper
    VUE安装并配置
    vue中router-view不显示
    vue打包后空白
  • 原文地址:https://www.cnblogs.com/hellogiser/p/zero-count-of-N-factorial.html
Copyright © 2020-2023  润新知