质因数分解小心得 2020年第十一届蓝桥杯javab组第三题阶乘约数

8 篇文章 0 订阅
2 篇文章 0 订阅

质因数分解是指将一个数分解成全由质数的X次方相乘的式子
设被质因子分解的数为:100
思路:for i = 1 to 100,如果i是合数(质数的反义词也可以说是非质数) 将被分解的数除以i并将i处的次方数+1

	public static void simple(int n) {
        int[] st = new int[n + 1];
        for (int i = 2; i * i <= n; i++) {
            if (n % i == 0) {
                while (n % i == 0) {
                    n /= i;
                    st[i]++;
                }
            }
        }
        // System.out.println(Arrays.toString(st));
    }

st[]为记录次方数的数组,因为记录的都是质数+[如果不能被<n的任意质数能分解,那么自己就会在st[n]的位置+1]。
一行行来分析

for (int i = 2; i * i <= n; i++) {
	// ...
}

这行代码其实是i <= Math.sqrt的变体,因为根号比平方要慢,所以写成这个样子,例如100可以分解成1 * 100, 2 * 50, 4 * 25, 10 * 10, 25 * 4, 50 * 2, 100 * 1。在10以后的等式其实都是10以前(包含10)的镜像翻转,比如2 * 50 和 50 * 2,那么其实1-100,我们只需要求前1-sqrt(100)就可以了,立方求因子也是这个思路 i * i 换成 i * i * i 就可以。

			if (n % i == 0) {
                // ...
            }

如果当前数能够被整除,意思就是当前数如果不是质数,因为质数是不能被整除的

                while (n % i == 0) {
                    n /= i;
                    st[i]++;
                }

如果当前这个数可以被整除,那么就把它的约数一点点分解掉,比如说100 = 4 * 25 = 2 * 2 * 5 * 5,这个while的作用就是从小到大一点点把因数给剥离开。
我们可以在最后一行加一句输出,看看st数组最终是什么样子的

[0, 0, 2, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

可以看到2和5的位置是2 说明 100 = 22 x 52
我们再来看题目


定义阶乘 n! = 1 × 2 × 3 × · · · × nn!=1×2×3×⋅⋅⋅×n。
请问 100!100! (100100 的阶乘)有多少个正约数。


如果使用暴力解法,会算到考试结束都算不出来 这里需要引入唯一分解定力来求,直接使用蓝桥杯决赛训练营的图(侵删)

在这里插入图片描述
上面已经了解了质因数分解,我们只需要从小到大求出每个质数的次方即可
将100!分解为: 1 * 2 * 3 * 4 * 5 。。。 * 100

		int[] st = new int[101];
        for (int j = 1; j <= 100; j++) { // 从1到100
            int k = j; // 不能让分解结果影响循环
            for (int i = 2; i * i <= k; i++) { // n 为被分解数
                // 以sqrt(n)为界 如果一个数在左边,必然有一个数在右边,不用求完 只需要求一半(i*i)就行 就可以判断是不是质数
                if (k % i == 0) {
                    // 不是质数 开始分解
                    while (k % i == 0) {
                        // 相除
                        k /= i;
                        st[i]++;
                        // 对应位置次数+1
                    }
                }
            }
            if (k > 1) {
                st[k]++;
            }
        }
        System.out.println(Arrays.toString(st));
        long l = 1;
        for (int i = 1; i < st.length; i++) {
            if (st[i] != 0) {
                l *= (st[i] + 1);
            }
        }
        System.out.println(l);

这样子代码就写出来了

			if (k > 1) {
                st[k]++;
            }

我们可以看到一重循环结束后有一个这个东西,可能有同学会觉得k可能会是合数影响结果,实际上k是2-100都不能除尽剩下的东西,它只能是个质数。所以并不需要担心这个数破坏了唯一分解定理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值