zoukankan      html  css  js  c++  java
  • 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: 如果觉得本文对你有帮助的话,那么【推荐】给大家吧,希望今后能够为大家带来更好的技术文章!敬请【关注】
  • 相关阅读:
    ELK
    alerta 集中化告警信息 -zabbix
    Python安装第三方模块出错 No module named setuptools
    Centos7 搭建bind9.9
    DNS 处理模块 dnspython
    varnish 项目实战
    中文版Postman测试需要登陆才能访问的接口(基于Cookie)
    fireFox模拟 post请求、上传插件,火狐浏览器中文postman插件
    MySQL单表最大记录数不能超过多少?
    ApiPost(中文版postman)如何发送一个随机数或者时间戳?
  • 原文地址:https://www.cnblogs.com/hellogiser/p/zero-count-of-N-factorial.html
Copyright © 2011-2022 走看看