唯一分解定理

唯一分解定理

1.内容

任何一个大于1的整数n都可以分解成若干个质数的连乘积,如果不计各个质数的顺序,那么这种分解是惟一的,即若n>1,则有
n = ∏ p i j n=\prod{p^j_i} n=pij
这里的 p i p_i pi是质数。

可以进行简单证明,假设 p i p_i pi是合数,那么它可以接着分解为两个数相乘的形式,所以最后 p i p_i pi一定是质数。

2.唯一分解定理模板代码

模板代码其实也是唯一分解定理的直接应用,给一个整数n,问有多少个质数是n的约数。这里就需要进行分解,也就是用到了唯一分解定理,我们直接上代码,然后逐一解释难懂的地方。

import java.util.Scanner;

public class Main {
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    long n = scanner.nextLong();
    int ans = 0;
    for (int i = 2; i <= Math.sqrt(n); i++) {
        if(n%i==0) ans++;
        while(n%i == 0) {
            n = n / i;
        }
    }
    if(n > 1) {
        ans++;
    }
    System.out.println(ans);
}
}
  1. 一般n可能给的很大,注意最好用long类型
  2. 我们如果要求一个数的因数,会从1开始遍历进行试除,那么应该遍历到哪里呢?是n吗?其实遍历到 n \sqrt{n} n 就可以了。因为如果找到了一个因子为a,那么大于 n \sqrt{n} n 的另一个因子就是n/a
  3. 很明显这个for循环我们是在采用试除法来求n的因子,但是我们如何保证求到的因子是质因子呢?这就是里面的while循环的作用了。给大家举个例子,n=36,6是它的因子,但是不是质因子,那么我们会不会遍历到它呢?i=2时,在while循环里就把36里的所有2都除没了,此时n=9。i=3时,在while循环里就把36里的所有3都除没了,此时n=1。那么此时的n里面已经不包含6了,因为6是由2和3构成的,在遍历到6之前,n里的所有的2和3都没有了,自然也就没有6了。这就是while循环的作用,他保证了我们找到的因子一定是质数
  4. 最后一个地方,为什么在代码的最后要加一个if判断呢?还是给大家举一个例子,比如n=396,i=2时,n=99。n=3时,n=11。当i=4时i> n \sqrt{n} n ,所以for循环退出了。但是你也可以发现,11也是n的一个质因子,所以我们在最后要判断一下,防止把这种情况漏了。

练习题目

3.应用

(1)求正整数n的正因子个数

假设n的分解公式如下,
n = p 0 j 0 ∗ p 1 j 1 ∗ p 2 j 2 . . . ∗ p k j k n=p^{j_0}_0*p^{j_1}_1*p^{j_2}_2...*p^{j_k}_k n=p0j0p1j1p2j2...pkjk
则n的因子个数为 ( j 0 + 1 ) ∗ ( j 1 + 1 ) ∗ ( j 2 + 1 ) . . . ∗ ( j k + 1 ) (j_0+1)*(j_1+1)*(j_2+1)...*(j_k+1) (j0+1)(j1+1)(j2+1)...(jk+1)个。

简单理解一下,对于 2 3 ∗ 3 2 ∗ 5 3 2^{3}*3^{2}*5^{3} 233253来说,可以选择一个2,其余质因子不选,则2是其因子,也可以选择两个2和一个3,则12是其因子,总的来说,假设n包含m个质因子p,则对于p我有m+1中选择,即[0,m]。

做个类比,我有红球3个,绿球5个,他们共有多少种不同的组合,肯定是46吧,那么n的因子个数为 ( j 0 + 1 ) ∗ ( j 1 + 1 ) ∗ ( j 2 + 1 ) . . . ∗ ( j k + 1 ) (j_0+1)*(j_1+1)*(j_2+1)...*(j_k+1) (j0+1)(j1+1)(j2+1)...(jk+1)同理。

模板代码如下,

import java.util.Scanner;

public class 约数个数 {
public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    long n = 1200000;
    int ans = 1;
    for (int i = 2; i <= Math.sqrt(n); i++) {
        int cnt = 0;
        while(n%i == 0) {
            n = n / i;
            cnt++;
        }
        ans *=(cnt+1);
    }
    if(n > 1) {
        ans *= 2;
    }
    System.out.println(ans);
}
}

练习题目

你可能感兴趣的:(java)