• 编程之美读书笔记之---”不要被阶乘吓到“


    问题一:给定一个整数N,那么N的阶乘末尾有多少个0呢?例如N = 10, N! = 362800,N! 的末尾有两个0.

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

    问题一的解法一:

    最简单的方法就是把N! 算出来,就可以知道末尾有多少个0了。

    问题一的解法二:

    我们这样想,末尾的0可以从哪里得到呢,10的倍数,例如像10,20,100....这样的,可以贡献0,还有就是2 * 5这样也可以得到一个0,不过我们可以发现,10其实也是从5得来的,

    10 = 2 * 5,

    20 = 4 * 5,

    100 = 20 * 5

    所以,我们可以得出,有多少个0,就看N!的因式分解中含有多少个5,。至此,成功的将原问题转化成一个更简单的问题。

    利用这个原理,我们提出两种解决方法求因式分解中因子5的个数:

    1、第一种方法很简单,就是直接拆分5出来

    int tot = 0;    //因子5的个数

    for(int i = 1;i <= N;i++)

    {

        int temp = i;

        while(temp % 5 ==0 )

        {

            tot++;

            temp /= 5;

        }

    }

    2、第二种方法tot = [N / 5] + [N / 5^2] + [N / 5^3]+.....看N除以5得多少,其实就是N!中,能被5整除的因子有多少个,然后每个因子可以贡献一个5,例如26!,[26/5] = 5,就有5,10,15,20,25这五个能被5整除的。然后能被5^2整除的因子可以贡献两个5,例如像25这样的,所以又要再加一次除以5^2的因子的个数,以此类推.....

    int tot = 0;

    int c = 5;

    while(c <= N)

    {

        tot += (tot / N);

        c *= 5;

    }

    问题二:

    我们知道一个整除除以2可以用右移1位来代替,当一个数可以被2整除的时候,二进制的最低位是0,当最低位是1的时候就是奇数,不能被2整除,所以,我们可以得出一个数可以被2整除多少次,就说明这个数的二进制最低位有多少个0。换一种说法就是这个数2的因子的个数。于是又有:

    一个数N的阶乘N!的二进制最低位0的个数 = [N / 2] + [N / 2^2] + [N / 2 ^ 3]+....

  • 相关阅读:
    PHP数组内容不重复组合排列算法
    【转】五种常见的 PHP 设计模式
    【转】PHP ob_start() 函数介绍
    【转】apache/php 开启 gzip压缩
    【转】HTTP 头部解释,HTTP 头部详细分析,最全HTTP头部信息
    【转】MySQL数据库MyISAM和InnoDB存储引擎的比较
    【转】PHP 位运算应用口诀
    require,include,require_once,include_once的区别
    Linux下Redis安装使用,主从模式,哨兵模式与PHP扩展(PHP7适用)
    php-fpm启动,重启,终止操作
  • 原文地址:https://www.cnblogs.com/xiaxiaosheng/p/4813091.html
Copyright © 2020-2023  润新知