【编程之美】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)