2.2 不要被阶乘吓倒

2.2 不要被阶乘吓倒

基本问题

1 给定一个正整数N,那么N的阶乘N! 末尾有多少个0呢?

在介绍解法之前,先介绍质因数分解
- 合数:合数是指在大于1的整数中除了能被1和本身整除外,还能被其他数(0除外)整除的数。
- 质数:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
- 质因数:每个合数都可以写成几个质数相乘的形式,这几个质数就都叫做这个合数的质因数。
- 质因数分解:正整数的因数分解可将正整数表示为一连串的质因子相乘,质因子如重复可以指数表示。根据算术基本定理,任何正整数皆有独一无二的质因子分解式。

解法

  • 解法1,暴力将N的阶乘求出来然后再进行计算,但是这种情况很有可能会出现溢出的情况,是非常不建议使用的。
  • 解法2 质因数分解方法,首先考虑\(N! = K * 10 ^ M\),而且K不能被10整除,那么末尾就有M个0,
    继续分析,\(N! = (2^x) * (3^y) * (5^z) * ....\)由于\(10 = 2 * 5\) 所以M只与x,y有关,\(M = min{x,y}\),因为被2整除比被5整除的数高得多,所以简化称为\(M = z\)
  • 解法3 上述的z可以表示为\(z = [n/5] +[n/5^2] +[n/5^3]+...\)
class Test{
	public static void main(String[] args) {
		System.out.println(zeroOfN(50));
		System.out.println(zeroOfN2(50));
	}
	// 问题1 解法1,暴力将N的阶乘求出来然后再进行计算,但是这种情况很有可能会出现溢出的情况,是非常不建议使用的。
	/** 质因数分解方法
	*/
	public static int zeroOfN(int n){
		int res = 0;
		for(int i = 1;i<=n;i++){
			int j = i;
			while(j%5 == 0){
				res++;
				j/=5;
			}
		}
		return res;
	}
	// 问题1 解法3
	/**
	上述的z可以表示为$z = [n/5] +[n/5^2] +[n/5^3]+...$
	*/
	public static int zeroOfN2(int n){
		int res = 0;
		while(n != 0){
			res+=n/5;
			n/=5;
		}
		return res;

	}
}

2 求N!的二进制表示中最低位1的位置

解法

  • 解法1 这个问题就相当于求N!中含有质因数2的个数,即答案等于N!含有质因数2的个数+1,N!中含有质因数2的个数等于\(N/2 + N/4 + N/8 + N/16 + ...\)
  • 解法2 N!含有质因数2的数目,还等于N减去N的二进制表示中1的数目
class Test{
	public static void main(String[] args) {
		System.out.println(posOfN(20));
		System.out.println(posOfN2(20));
	}
	// 问题2 解法1 
	/**
	这个问题就相当于求N!中含有质因数2的个数,即答案等于N!含有质因数2的个数+1
	N!中含有质因数2的个数等于$N/2 + N/4 + N/8 + N/16 + ...$
	*/
	public static int posOfN(int n){
		int res = 0;
		while(n != 0){
			n>>=1;
			res+=n;
		}
		return res;

	}
	// 问题2 解法2
	/**
	N!含有质因数2的数目,还等于N减去N的二进制表示中1的数目
	*/
	public static int posOfN2(int N){
		int t = 0;
		int tmp = N;
		while(tmp != 0){
			t++;
			tmp&=(tmp-1);
		}
		return N-t;
	}
}

拓展问题

拓展问题:给定一个整数,判断他是否是2的幂


class Test{
	public static void main(String[] args) {
		// true
		System.out.println(is2(2));	
	}
	// 拓展问题:给定一个整数,判断他是否是2的幂
	public static boolean is2(int n){
		return (n>0) &&((n&(n-1)) == 0);
	}
}

posted @ 2020-11-18 22:37  BOTAK  阅读(111)  评论(0编辑  收藏  举报