数论——质数讲解
质数
定义:质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。或叫素数。否则称为合数,规定1既不是素数也不是合数
判断质数
试除法
例题
给定 n 个正整数 ai,判定每个数是否是质数。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个正整数 ai。
输出格式
共 n 行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出 Yes,否则输出 No。
数据范围
1≤n≤100,
1≤ai≤2^31−1
输入样例:
2
2
6
输出样例:
Yes
No
方法1 :假设要判断的数是n, 枚举2 ~ n - 1这些数,如果这些数中存在能够整除n的数,则说明n是合数,否则为质数
n = int(input())
def is_prime(x) :
if x < 2 :
return False
for i in range(2, x) :
if x % i == 0 :
return False
return True
for i in range(n) :
x = int(input())
if is_prime(x) :
print("Yes")
else :
print("No")
这个算法的时间复杂度是O(n)
方法2 :改进方法1,我们知道如果存在d | n,那么n的另一个因子为n / d,则(n / d)| n。所以我们只要枚举min(d, n / d)中的数,for(i = 2 ; i < n / d ; i++)
n = int(input())
def is_prime(x) :
if x < 2 :
return False
i = 2
while i <= x // i :
if x % i == 0 :
return False
i += 1
return True
for i in range(n) :
x = int(input())
if is_prime(x) :
print("Yes")
else :
print("No")
优化后的时间复杂度为O(sqrt(n))
求解数的质因子
概要
质因子(或质因数)在数论里是指能整除给定正整数的质数。根据算术基本定理,不考虑排列顺序的情况下,每个正整数都能够以唯一的方式表示成它的质因数的乘积。
一个质数n最多只有一个大于根号n的质因子
试除法
例题
给定 n 个正整数 ai,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。
输入格式
第一行包含整数 n。
接下来 n 行,每行包含一个正整数 ai。
输出格式
对于每个正整数 ai,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。
每个正整数的质因数全部输出完毕后,输出一个空行。
数据范围
1≤n≤100,
2≤ai≤2×109
输入样例:
2
6
8
输出样例:
2 1
3 1
2 3
n = int(input())
def divide(x) :
i = 2
while i <= x // i :
if x % i == 0:
s = 0
while x % i == 0 :
s += 1
x //= i
print(i, s)
i += 1
if x > 1 :
print(x, 1)
print()
for i in range(n) :
a = int(input())
divide(a)
说明一下,由于从小到大枚举质数个数,一个阶段i的x中不会存在(1 ~ i - 1)的质因子,这样也一定不会存在一个合数i能整除它。
筛质数
两种筛法
给定一个正整数 n,请你求出 1∼n 中质数的个数。
例题
输入格式
共一行,包含整数 n。
输出格式
共一行,包含一个整数,表示 1∼n 中质数的个数。
数据范围
1≤n≤106
输入样例:
8
输出样例:
4
难度:简单
时/空限制:0.2s / 64MB
埃氏筛法
埃拉托斯特尼筛法,简称埃氏筛或爱氏筛,是一种由希腊数学家埃拉托斯特尼所提出的一种简单检定素数的算法。要得到自然数n以内的全部素数,必须把不大于根号n的所有素数的倍数剔除,剩下的就是素数。
算法步骤
试除法枚举所有数,在枚举的过程中将质数的倍数全部筛为合数,只要后面的数未被判断为合数,那就是质数
N = 1000010
prime = []
st = [True] * N
n = int(input())
def get_prime(x) :
cnt = 0
for i in range(2, n + 1) :
if st[i] :
cnt += 1
prime.append(i)
j = i + i
while j <= x :
st[j] = False
j += i
return cnt
print(get_prime(n))
线性筛
在埃氏筛的基础上保证每个数都是由其最小质数筛掉的
N = 1000010
prime = []
st = [True] * N
n = int(input())
def get_prime(x) :
cnt = 0
for i in range(2, x + 1) :
if st[i] :
prime.append(i)
cnt += 1
for j in prime :
if i * j > n :
break
st[i * j] = False
if i % j == 0 :
break
return cnt
print(get_prime(n))
线性筛的精髓
if i % j == 0 : break
,保证了每次都不会用更大的质因子更新,且避免了重复更新
总结
大二密码学用过的数论全都还回去了,质数的讲解有助于我们更好的更快的判断质数,找到质因子,列出一定范围内的质数
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· NetPad:一个.NET开源、跨平台的C#编辑器
· PowerShell开发游戏 · 打蜜蜂
· 凌晨三点救火实录:Java内存泄漏的七个神坑,你至少踩过三个!