关于N的阶乘中的一些数学计算技巧
N的阶乘中末尾有几个0
分析:如果N的阶乘可以写成$K * 10^m$,并且K不能被10整除,那么(N!)末尾有m个0。其次,可以根据ugly number的分析,对N!进行质因数分解,$(N!) = 2^x * 3^y * 5^z$,所以m只能跟x和z相关,m = min{x, z}。x>=z,因为能被2整除的数出现的频率比能被5整除的数高得多,所以把公式可以简化为求n!中质因数5的个数1
2
3
4
5
6
7
8
9
10
11
12int numberOfFive(int N){
int count= 0;
for(int i = 1; i <= N; i++){
int j = i;
while(j % 5 == 0){
count++;
j /= 5;
}
}
return count;
}
另一种方法:
N!中质因数5的个数为:
$[N/5] + [N/25] + [N/5^3]+...$1
2
3
4
5
6
7
8
9int numberOfFive2(int N){
int count = 0;
while(N){
ret += N/5;
N /= 5;
}
return count;
}
N的阶乘的二进制最低位1的位置
例如,给出N = 4,N! = 24(11000),返回的是4.
这个问题可以转化为求出N!含有质因数2的个数。答案为质因数2的个数加一。
1 | int numberOfTwo(int N){ |
怎么能随机生成m个数,让其和等于n
题目: 假设生成26个非负随机数,要求其和是200,求程序生成此列数字。
解法一思路:把这道题想象成是将一根长200的绳子分割成26份,
1.初始化长度为27的数组
- a[0] = 0, a[26] = 200,其它位置随机填充0到200的值(不能重复)
- 对数组排序
- 相邻的数字相减,就是所要求的26个数字
解法二:因为非负,就是将1随机加到一个26位的数组中,随机200次。