【编程之美】2.2 阶乘

题目1:找出n!中末尾0的个数。

#include <stdio.h>

//输入n 输出n!中末尾0的个数
//分析:只需要知道n!中质因子5出现了多少次 因为2*5 = 10 因子2比5多 只需要关注5
//方法1: 对1...n的每个数字 循环除以5 相加得到总共因子5的个数 
//注意:像25这样的数字提供了2个5
int numOfZero1(int n)
{
    int ans = 0;
    for(int i = 1; i <= n; i++)
    {
        int j = i;
        while(j % 5 == 0)
        {
            ans++;
            j = j / 5;
        }
    }
    return ans;
}

//方法2: 总共因子5出现的个数 = 小于等于n的中5的倍数的数字的个数 + 小于等于n/5中5的倍数的数字的个数 + 小于等于n/25中5的倍数的数字的个数 +....
//其实就是每个可以除开5的数字贡献了一个5,可以除开25的又多贡献了一个5...
//方法2快一些
int numOfZero2(int n)
{
    int ans = 0;
    while(n)
    {
        n = n / 5;
        ans += n;
    }
    return ans;
}

int main()
{
    int a = numOfZero2(25);
    int b = numOfZero1(25);

    return 0;
}

 

 

题目2:找到n!的二进制表示中最低位1的位置。

这个我没做出来,还有最开始看题不仔细,当成10进制的了,要注意仔细读题。

书上答案:考虑除以2操作。 若2进制最低位为0,除以2就是右移1位,若最低位是1,则除不开2. 故最低1的位置就是 n!可以除开2的次数+1

方法1:跟上面题目的一样,不过是因子5换成了因子2而已 最后再加个1

方法2:n!中因子2的个数还等于 n - n的2进制表示中1的个数

int LowestOne1(int n)
{
    int ans = 0;
    while(n)
    {
        n = n >> 1;
        ans += n;
    }
    return ans + 1;
}

int LowestOne2(int n)
{
    int numof1 = 1;
    int ntmp = n;
    for(;(ntmp = ntmp&(ntmp-1))!= 0; numof1++);
    return n - numof1 + 1;
}


int main()
{
    int c = LowestOne1(15);
    int d = LowestOne2(15);

    return 0;
}

 

题目3:判断一个数是否是2的幂

思路:2的幂肯定其2进制表示只有最高位1个1,并且数字必须大于0 故 判断条件为

(n > 0 && n&(n - 1) == 0)

posted @ 2014-10-30 22:35  匡子语  阅读(493)  评论(0编辑  收藏  举报