学习指引
- 序、专栏前言
- 序、本章前言
- 算术基本定理
- 一、【例题1】
- 1、题目描述
- 2、解题思路
- 3、模板代码
- 4、代码解析
- 三、推荐专栏
- 四、课后习题
序、专栏前言
本专栏开启,目的在于帮助大家更好的掌握学习Java
,特别是一些Java学习者
难以在网上找到系统地算法学习资料帮助自身入门算法
但最最主要的还是需要独立思考,对于本专栏的所有内容,能够进行完全掌握,自己完完全全将代码写过一遍,对于算法入门肯定是没有问题的。
算法的学习肯定不能缺少总结,这里我推荐大家可以到高校算法社区将学过的知识进行打卡,以此来进行巩固以及复习。
学好算法的唯一途径那一定是题海战略,大量练习的堆积才能练就一身本领。专栏的任何题目我将会从【题目描述】【解题思路】【模板代码】【代码解析】等四板块进行讲解。
序、本章前言
算术基本定理是一个非要重要的定理,它的存在是许多重要公式的基础,比如前两天我们学习的约数个数和约数之和算法。它都是建立在算术基本定理上,当时我们直接进行了质因数分解的,可能有的小伙伴还不太理解。今天我们系统来进行讲解一下
算术基本定理
的
自然数
,如果
不为
质数
,那么可以唯一分解成有限个数的乘积:
其中指数均为正整数,这样的分解式称为
的标准分解式。最早是由欧几里得证明给出。 算术基本定理的证明在此我们不细讲,拓展一些基于算术基本定理可以得到的一些证明。
约数之和定理,
的所有正因数之和:
对于两个整数
和
,有
=
说明素数的个数是无限的。
一、【例题1】
1、题目描述
个正整数
,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。
2、解题思路
由于需要分解多个数,所以我们将分解一个数的操作抽成一个函数进行操作
注意
的范围很大,我们使用
long
读取。
3、模板代码
import java.util.*;
public class a {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
for (int i = 0; i < n; i++) {
long x=sc.nextLong();
test(x);
}
}
static void test(long x){
for (int i = 2; i <=x;i++) {
if (x%i==0){
int ans=0;
while (x%i==0){
x/=i;
ans++;
}
System.out.println(i+" "+ans);
}
}
}
}
但很明显我们发现,设每个数的取值范围为,时间复杂达到了
,这是不可接收的,我们考虑对
test
函数进行优化
static void test(long x){
for (int i = 2; i <=x/i;i++) {
if (x%i==0){
int ans=0;
while (x%i==0){
x/=i;
ans++;
}
System.out.println(i+" "+ans);
}
}
if (x>1) System.out.println(x+" "+1);
}
4、代码解析
很明显,对于
复杂度的
test
操作我们优化为。它基于的原理是对于一个正整数
,它的质因数中大于
的最多只能有一个。这也很好证明,假设有两个,那么相乘肯定大于
了。
所以对于每个数
,我们不需要完全遍历,只需要遍历到
的级别即可,最后判断
是否大于
,如果大于说明它此时就是那个大于
的质因数。
课后习题
序号 | 题目链接 | 难度评级 |
1 | 丑数3 | 2 |