【蓝桥杯】简单数论3——素数

news2024/9/22 3:46:38

1、素数判断

素数定义:只能被1和自己整除的正整数。注:1不是素数,最小素数是2。

判断一个数n是不是素数:当n≤10^{14}时,用试除法;n>10^{14}时,试除法不够用,需要用高级算法,例如Miller_Rabin算法。

试除法:用[2, n-1]内的所有数去试着除n,如果都不能整除,就是素数。

  • 优化1:把[2, n-1]缩小到[2, √n]。证明:若n= a×b,其中a≤√n,b>√n,如果n有个因子是a,说明n不是素数,b不用再试。
  • 优化2:提前算出[2, √n]范围内的所有素数,用这些素数来除n就行了。埃氏筛用到这一原理。范围[2,√n]内有多少个素数?在1百万以内,约有7.8万个素数;在1亿以内,约有576万个素数,提高了十几倍的速度。但一般只需要用优化1即可。
from math import*
def is_prime(n):                #若n是素数,返回true
    if n == 1: return False     #1不是素数
    m = int(sqrt(n)+1)          #sqrt(n),也可以这样写n**0.5
    for i in range(2, m):
        if n % i == 0: 
            return False        #不是素数
    return True                 #是素数

 例题一:选数

lanqiao0J题号753

题目描述

已知 n 个整数 1,2,⋯,x1​,x2​,⋯,xn​,以及一个整数 k(k<n)。从 n 个整数中任选 k 个整数相加,可分别得到一系列的和。例如当 n=4,k=3,4个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为:

3+7+12=22            3+7+19=29            7+12+19=38            3+12+19=34。

现在,要求你计算出和为素数共有多少种。 例如上例,只有一种的和为素数:3+7+19=29。

输入描述

输入格式为:

第一行:n,k(1≤n≤20,k<n)

第二行:x1​,x2​,⋯,xn​(1≤xi​≤5×106)

输出描述

一个整数(满足条件的种数)。

输入输出样例

输入

4 3
3 7 12 19 

输出

1

先得到从s中选出k个的所有组合,使用combinations()函数,然后判断这些组合的和是否为素数。

from math import *
from itertools import * # combinations(s,k)需要导入这个库
def is_prime(n):
    if n == 1: return False
    m = int(sqrt(n)+1)#sqrt(n)可以这样写n**0.5
    for i in range(2, m):
        if n % i == 0: return False
    return True
n, k = map (int, input ().split())
s = list (map(int, input ().split()))
cnt = 0
for e in combinations(s,k): # 从s中选出k个的所有组合
    num= sum(e)             #求和
    if is_prime (num) == True: cnt+=1
print(cnt)

例题二:笨小猴 

lanqiao0J题号527

题目描述

笨小猴的词汇量很小,所以每次做英语选择题的时候都很头疼。但是他找到了一种方法,经试验证明,用这种方法去选择选项的时候选对的几率非常大!

这种方法的具体描述如下:假设 maxn 是单词中出现次数最多的字母的出现次数,minn 是单词中出现次数最少的字母的出现次数,如果 maxn−minn 是一个质数,那么笨小猴就认为这是个 Lucky Word,这样的单词很可能就是正确的答案。

输入描述

输入一行,是一个单词,其中只可能出现小写字母,并且长度小于 100。

输出描述

输出两行,第一行是一个字符串,假设输入的的单词是Lucky Word,那么输出Lucky Word,否则输出No Answer

第二行是一个整数,如果输入单词是 Lucky Word,输出 maxn−minn 的值,否则输出 0。

输入输出样例

示例 1

输入

error

输出

Lucky Word
2

示例 2

输入

Olympic

输出

No Answer
0

模拟,统计每个字母出现的次数s.count(i),然后判断maxn-minn是否为素数。

from math import *
def is_prime(n):
    if n == 0 or n==1:return False
    m = int(sqrt(n)+1)
    for i in range(2,m):
        if n%i == 0:  return False
    return True
s = input()
maxn= -1    # 反向初始化(最大值初始化为最小,最小值初始化为最大)
minn= 1000
for i in s: # 找出最最小值
    n=s.count(i)
    maxn=max(maxn,n)
    minn=min(minn,n)
if is_prime(maxn-minn):print("Lucky Word");print(maxn-minn)
else:                  print("No Answer");print(0)

例题三: 最大最小公倍数

lanqiao0J题号1510

题目描述

已知一个正整数 N,问从 1∼N 中任选出三个数,他们的最小公倍数最大可以为多少。

输入描述

输入一个正整数 N。1≤N≤10^6。

输出描述

输出一个整数表示答案。

输入输出样例

输入

9

输出

504

思路:贪心

  • 贪心题,从大的数开始选。不过,简单地把N里面最大的三个数相乘,N*(N-1)*(N-2),并不正确,需要分析多种情况。
  • 最小的公倍数是三个数的质因数相乘,如果有几个质因数相同,则比较两数中哪个数的质因数的个数较多。例如6、7、8的最小公倍数,先分解因子:6=2×3,7=7×1,8=2×2×2,它们的最小公倍数是3×7×2×2×2。
  • 大于1的两个相邻整数互质,它们没有公共的质因数。如果题目是任选二个数,最大的最小公倍数是N*(N-1)

对于连续的最大三个整数,分两种情况:
(1)N是奇数。N、N-1、N-2是奇偶奇,结论是这三个数两两互质,三个数的乘积就是最大的最小公倍数。三个数两两互质,也就是说任意一个质数,只在N、N-1、N-2中出现一次。连续的三个整数的质因数必有2和3,奇数N的质因数可能仅有3,但有且仅有N-1有质因数2。所以N是奇数,那么N、N-1、N-2互质。

证明:下面对这两个质数分析:

  • 质因数2,只在N-1中出现。
  • 质因数3,如果在N中出现(设N=3a,a为整数),就不会在N-1中出现(这要求N-1 = 3b,,n为整数,N无整数解),也不会在N-2中出现(这要求N-2= 3b,N无整数解)。

结论:推广到任何一个质数k,都只会在N、N-1、N-2中出现一次,所以三个数互质。

(2)N是偶数。 N的质因数要么有2和3两个质数,要么有2一个质数

  • 质因数2,N和N-2有公因子2;
  • 质因数3,若设N= 6a,N-1=6b, N-2=6c。由上面质因数3的分析可知,质数3只会出现在N中

结论:如果偶数N中有质因数3,那么N、N-1、N-2互质,否则N、N-1、N-3互质(因为只有N有质因数2)。

n = int(input())
if n <= 2: print(n)
elif n % 2 != 0:  # n是奇数
    print(n * (n - 1) * (n - 2))
else:             # n是偶数
    if n % 3 == 0: print((n-1)*(n-2)*(n-3))# n有因数3
    else:print (n*(n-1)*(n-3))             # n没有因数3

 2、素数筛

  • 素数的筛选:给定n,求2~n内所有的素数。
  • 一个个地判断很慢,所以用“筛子”筛所有的整数,把非素数筛掉,剩下的就是素数。
  • 常用两种筛法:埃氏筛、欧拉筛。

2.1埃氏筛

初始队列{2、3,4,5,6,7,8,9,10,11,12,13,...,n},操作步骤:
...
(1)输出最小的素数2,筛掉2的倍数,得{3,5,7,9,,11,13,...}

(2)输出最小的素数3,筛掉3的倍数,得{5,7,11,13,...}

(3)输出最小的素数5,筛掉5的倍数,得{7,11,13,...}

继续以上步骤,直到队列为空。

例题四:质数(模板题)

lanqiao0J题号1557​​​​​​​

题目描述

给定一个正整数 N,请你输出 N 以内(不包含 N)的质数以及质数的个数。

输入描述

输入一行,包含一个正整数 N。1≤N≤1000

输出描述

共两行。

第 1 行包含若干个素数,每两个素数之间用一个空格隔开,素数从小到大输出。

第 2 行包含一个整数,表示N以内质数的个数

输入输出样例

输入

10

输出

2 3 5 7
4
  • vis[i]记录数i的状态,若vis[i]=1,表示它被筛掉,不是素数。
  • prime[ ]存放素数,prime[0]是第一个素数2。
  • E_sieve(n)函数用来做筛除的数2、3、5......等,最多到\sqrt{n}就可以了。例如,求n =100以内的素数,用2、3、5、7筛就足够了。原理和试除法一样:非素数k,必定可以被一个小于等于的素数整除,被筛掉。
from math import *
def E_sieve(n) : # 埃氏筛
    for i in range (2,int (sqrt(n)+1)):
        if not vis[i]:    # 没有被筛过,是素数
            for j in range(i*i, n+1,i):    # 开始筛该素数的倍数
                vis[j] = 1
    k=0
    for i in range (2, n+1):   #存素数
        if not vis[i]:    # 没有被筛
            prime[k] = i  # 是素数。可以不需要用prime存,直接打印即可print(vis[i],end=" ")
            k += 1
    return k
N= int(1e6)
prime =[0]*N
vis = [0]*N
n = int (input())
k= E_sieve(n-1)
for i in range (0,k): print (prime[i], end=" ")
print ()
print (k)

 3、区间素数

埃氏筛法求[2, n]内的素数,只能解决规模n<10^7的问题。如果n更大,在某些情况下,也可以用埃氏筛法来处理,这就是大区间素数的计算。
把埃氏筛法扩展到求区间[a, b]的素数,a<b<10^{12},b-a≤10^6

方法:先用埃氏筛法求[2,\sqrt{n}]内的素数,然后用这些素数来筛[a,b]区间的素数

例题五:找素数(模板题)

lanqiao0J题号1558

题目描述

给定一个区间 [a,b],请你求出该区间内有多少个素数。

输入描述

输入共一行,包含两个整数 a,b。

2≤a≤b≤2^{31},b−a≤1000000

输出描述

输出一个整数,表示答案。

输入输出样例

输入

2 6

输出

3

题解: 

本题a,b<= 2^{31} ,不能直接定义一个vis[N],N=2^{31}来表示[0,b]内的每个数字,空间太大。
只能定义区间大小的空间,即N=1000000。

from math import *
def seg_sieve(a, b):
    for i in range(2,int(sqrt(b))+1):   # 先用埃氏筛求2~√n的素数
        if vis[i]== True:                      # 是素数
            for j in range(i*i,int(sqrt(b)),i):
                vis[j]=False
            # 再求[a, b]的素数
            for j in range(max(2,(a+i-1)//i)*i, b+1,i): # 难点:处理起点:max(2,(a+i-1)//i)*i,从当前素数i的倍数开始筛
                seg_prime[j-a]=False
    num= 0
    # 统计[a, b]的素数个数
    for i in range(0, b-a+1):
        if seg_prime[i]:
            prime[num] = i+a
            num += 1
    print(num)
N = 1000005 # 稍微大一点(保险)
vis = [True]*N          # 标记[2, sqrt(b)]是否为素数
prime = [0]*N           # 存[a, b]的素数
seg_prime = [True] * N  # 标记[a, b]是否为素数
a, b = map(int,input ().split())
seg_sieve(a,b)

4、分解质因子

任何一个正整数n都可以唯一地分解为有限个素数的乘积n=p_1^{c1}p_2^{c2}...p_m^{cm},其中c_i都是正整数,p_i都是素数且从小到大
分解质因子也可以用试除法。求n的质因子:
(1)第一步,求最小质因子p_1。逐个检查从2到\sqrt{n}的所有素数,如果它能整除n,就是最小质因子。然后连续用p_1除n,目的是去掉n中的p_1,得到n_1

 (2)第二步,再找n_1的最小质因子。逐个检查从p,到的所有素数。从p_1开始试除,是因为n_1没有比p_1小的素因子,而且n_1的因子也是n的因子。

 (3)继续以上步骤,直到找到所有质因子。

例题六:寻找质因子 

题目描述

给定一个区间 [a,b],请你求出区间 [a,b] 中所有整数的质因数分解。

输入描述

输入共一行,包含两个整数 a,b。

2≤a≤b≤10000。 

输出描述

每行输出一个数的分解,形如 k=a1​×a2​×a3​⋯(a1​≤a2​≤a3​⋯,k也是从小到大的)(具体可看样例)

输入输出样例

输入

3 10

输出

3=3
4=2*2
5=5
6=2*3
7=7
8=2*2*2
9=3*3
10=2*5

题解:

直接对每个数进行分解,然后打印出它的因数。

def s(x):#返回x的第一个因子
    for i in range(2,int(x**0.5)+1):
        if x%i==0:return i
    return x        # 若没有找到因子,返回本身
a, b = map(int,input ().split())
for x in range(a, b+1):
    print(x,end="") ; print( '=', end="")
    while x!=1:
        ans = s(x)    # 求最小质因数
        if x/ans != 1: print(ans, end="") ; print('*', end="")
        else:print (int(ans)) # 质因子是本身,直接输出
        x /=ans               # 除掉最小质因子,继续找下一个最小质因子

例题七:数的拆分

2022年第十三届省赛lanqiao0J题号2090

问题描述

给定 T 个正整数 ai​, 分别问每个 ai​ 能否表示为 x1^{y1}*x2^{y2}的形式, 其中 x1​,x2​ 为正整数, y1​,y2​ 为大于等于 2 的正整数

输入格式

输入第一行包含一个整数 T 表示洵间次数。

接下来 T 行, 每行包含一个正整数 ai​ 。

输出格式

对于每次询问, 如果 ai​ 能够表示为题目描述的形式则输出 yes, 否则输出 no.

样例输入

7
2
6
12
4
8
24
72

样例输出

no
no
no
yes
yes
no
yes

样例说明

第 4,5,74,5,7 个数分别可以表示为:

a4​=2^2*1^2

a5​=2^3*1^2

a7​=2^3*3^2

评测用例规模与约定

对于 10%1 的评测用例, 1≤T≤200,ai​≤10^9;

对于 30% 的评测用例, 1≤T≤300,ai​≤10^18;

对于 60% 的评测用例, 1≤T≤10000,ai​≤10^18;

对于所有评测用例, 1≤T≤100000,1≤ai​≤10^18

 题解:

例:24不行,因为24=3^1*2^3。72可以,因为72=2^3*3^2
数据规模ai≤10^{18},即使用之前的优化方法:遍历2~\sqrt{a_i}(即2~10^9)也是不能通过所有测评用例。​​​​​​​

对a进行素因子分解a= p^{q1}_1p^{q2}_2
重点:题目要求q_i≥2,拆分q_i=k_1y_1+k_2y_2,k_1,k_2\geq 0,y_1,y_2\geq 2y_1=2,y_2=3可以保证所有q_i\geq 2均有非负整数解。
q_i=ky_1+ ky_2= 2k_1+3k_2= k对于任意k>1都有非负整数解,例如:

  • k %3=0,k_1=0,k_2= k/3
  • k %3=1,k_1=2,k_2=(k-4)/3
  • k %3=2,k_1,= 1,k_2=(k-2)/3

问题变成a是否能分解为x_1^2x_2^3,检测每个q_i是否大于等于2,只要大于等于2,就可以按对应的k分配到x_1,x_2

本题a≤10^18,所以x_1^2x_2^3=10^{18},当素因子p >4000时p^5 \geqslant 10^{18}​​​​​​​,只需要暴力判断4000以内的素因子,对于大于4000的p,指数只能是2、3、4判断是否为平方数或立方数即可

时间复杂度:
用埃氏筛预计算p=.4000以内的素数,O(p^2)。
然后进行判断,O(T*550),550是4000以内的素数个数。

from math import *
N = 4000
prime = [0]*N
vis = [0]*N
cnt = 0
def E_sieve(): # 预计算4000以内的素数
    global cnt
    for i in range(2,N):
        if not vis[i]: cnt+=1; prime[cnt] = i
        for j in range(i*i,N,i):vis[j] = 1
def solve() :
    a = int(input())
    for i in range (1, cnt+1):   # 遍历4000以内所有素数
        c = 0                    # 统计因子个数
        while a % prime[i] == 0: # 能被整除,
            a/=prime[i]
            c+=1                 # 次方+1
        if c==1: print("no"); return   # 次方数为1,不合题意
    k = int(sqrt(a))
    if k*k == a: print("yes"); return  # 检查n是否为平方数
    k = int (pow(a,1/3))
    if k*k*k==a: print("yes"); return   # 检查n是否为立方数
    print("no")
E_sieve()
T=int(input())
for i in range(T): solve()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177311.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL —— 库操作

目录 一、库操作 1. 创建数据库 2. 创建数据库案例 二、字符集和校验规则 1. 查看系统默认字符集以及校验规则 2. 查看数据库支持的字符集 3. 查看数据库支持的字符集校验规则 4. 校验规则对数据库的影响 三、操纵数据库 1. 查看数据库 2. 显示创建语句 3. 修改数…

Pandas 数据可视化

数据可视化Joyful Pandas基本绘图动手学数据分析2 第二章&#xff1a;数据可视化2.7 如何让人一眼看懂你的数据&#xff1f;2.7.1 任务一2.7.2 任务二2.7.3 任务三2.7.4 任务四2.7.5 任务五2.7.6 任务六2.7.7 任务七Joyful Pandas Datawhale社区 Joyful Pandas 基本绘图 一维…

《深入浅出计算机组成原理》学习笔记 Day9

乘法器1. 顺序乘法2. 并行加速方法3. 电路并行参考1. 顺序乘法 以 13913 \times 9139为例&#xff0c;131011012,9101001213_{10} 1101_2, 9_{10} 1001_21310​11012​,910​10012​。用列竖式的方式计算&#xff1a; 在二进制下&#xff0c;由于只有 0 和 1&#xff0c;计…

逆序对问题、树状数组与离散化

目录 一、前言 二、逆序对问题 1、暴力法 2、归并排序法 3、树状数组与逆序对&#xff08;最巧妙最好的方法&#xff09; &#xff08;1&#xff09;倒序 &#xff08;2&#xff09;正序 &#xff08;3&#xff09;离散化 三、例题 1、小朋友排队&#xff08;lanqiao…

springBoot——SpringBoot 整合 Mybatis 流程

SpringBoot 整合持久层SpringBoot 整合 Mybatis 流程一、添加依赖1. pom.xml二、写配置文件1. application.yml三、写 Java 文件1. entity2. dao3. service4. controller5. mapper四、建立数据库五、测试SpringBoot 整合 Mybatis-Plus 流程一、添加依赖1. pom.xml二、写配置文件…

linux基本功系列之chattr命令

文章目录一. chattr命令介绍二. 语法格式及常用选项三. 参考案例3.1 给指定文件添加隐藏属性&#xff0c;阻止文件被修改&#xff1a;3.2 撤销i属性3.3 允许补充&#xff08;追加&#xff09;内容&#xff0c;无法覆盖/删除内容总结前言&#x1f680;&#x1f680;&#x1f680…

LabVIEW监控操纵杆,键盘或鼠标

LabVIEW监控操纵杆&#xff0c;键盘或鼠标在LabVIEW中从操纵杆/鼠标/键盘获取数据在LabVIEW中监控我的输入设备如何知道键盘上按了哪些键&#xff1f;用轮询的方式监控鼠标&#xff0c;键盘或操纵杆的动作。要在LabVIEW中监控这些设备&#xff0c;可以使用内置的输入设备采集VI…

【STM32】寄存器原理

如果我们想要深入去学习STM32单片机的存储原理和方式&#xff0c;就要花时间去了解STM32单片机有关寄存器的基本原理 单片机型号&#xff1a;正点原子STM32F103ZET6 目录 寄存器的定义 寄存器分类 存储器映射 寄存器映射 通过地址访问控制单元运作 通过定义宏来取代直接访…

C++ 哈希表查询_进入哈希函数结界的世界

1. 前言 哈希表或称为散列表&#xff0c;是一种常见的、使用频率非常高的数据存储方案。 哈希表属于抽象数据结构&#xff0c;需要开发者按哈希表数据结构的存储要求进行 API 定制&#xff0c;对于大部分高级语言而言&#xff0c;都会提供已经实现好的、可直接使用的 API&…

基于PythonOpenCv的视频图像处理

博主简介 博主是一名大二学生&#xff0c;主攻人工智能研究。感谢让我们在CSDN相遇&#xff0c;博主致力于在这里分享关于人工智能&#xff0c;c&#xff0c;Python&#xff0c;爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主&#xff0c;博主会继续更新的&#xff0c…

【教程】虚拟环境与Pytorch安装保姆级教学

【教程】虚拟环境与Pytorch安装保姆级教学NVIDIA驱动安装虚拟环境创建激活/退出相关库的安装Pycharm内设置虚拟环境Pytorch安装安装地址可能遇到的问题处理报错安装卡顿测试是否安装完成参考NVIDIA驱动安装 NVIDIA驱动可在官网进行安装&#xff1a;NVIDIA驱动官网 命令行输入…

一文上手决策树:从理论到实战

一、基础概念 决策树是一类极为常用的机器学习方法&#xff0c;尤其是在分类场景。决策树通过树形结构来递归地将样本分割到不同的叶子结点中去&#xff0c;并根据每个叶子结点中的样本构成对该结点中的样本进行分类。 我们可以从两个视角来理解决策树模型。 第一种视角是将…

Python副业技术总结,手把手教你用宝塔面板部署Django程序

前言 最近写了几个Django项目&#xff0c;写完以后怎么让对方测试成了问题&#xff0c;因为之前都是自己在本地写的练习项目&#xff0c;对于部署这一块很陌生&#xff0c;不知道怎么操作&#xff0c;内心很忐忑。没办法&#xff0c;只能硬着头皮上&#xff0c;一边百度&#…

17种编程语言实现排序算法-插入排序

开源地址 https://gitee.com/lblbc/simple-works/tree/master/sort/ 覆盖语言&#xff1a;C、C、C#、Java、Kotlin、Dart、Go、JavaScript(JS)、TypeScript(TS)、ArkTS、swift、PHP。 覆盖平台&#xff1a;安卓(Java、Kotlin)、iOS(SwiftUI)、Flutter(Dart)、Window桌面(C#)、…

ARP渗透与攻防(四)之WireShark截获用户数据

ARP-WireShark截获用户数据 系列文章 ARP渗透与攻防(一)之ARP原理 ARP渗透与攻防(二)之断网攻击 ARP渗透与攻防(三)之流量分析 1.WireShark工具介绍 wireshark的官方下载网站&#xff1a; WireShark wireshark是非常流行的网络封包分析软件&#xff0c;功能十分强大。可以…

PowerShell 学习笔记:压缩、解压缩文件

在自动构建的时候&#xff0c;最常用的就是压缩备份项目的源文件&#xff0c;PowerShell提供了相关命令。Compress-Archive&#xff08;压缩文件&#xff09;Compress-Archive[-Path] <String[]>[-DestinationPath] <String>[-CompressionLevel <String>][-P…

Crossplane - 比 Terraform 更先进的云基础架构管理平台?

&#x1f449;️URL: https://crossplane.io/ &#x1f4dd;Description: 将云基础架构和服务组成自定义平台 API 简介 在 11 月的 KCD 上海现场&#xff0c;听了一场阿里云的工程师关于他们自己的多云基础架构管理工具的介绍&#xff0c;前边的引言部分有介绍到 Terraform&am…

连续系统的数字PID控制仿真-3

在连续系统的数字PID控制仿真-2的基础上&#xff0c;利用S函数实现PID离散控制器的Simulink仿真。在S函数中&#xff0c;采用初始化函数、更新函数和输出函数&#xff0c;即 mdlInitializeSizes函数、mdIUpdates函数和mdlOutputs函数。在初始化中采用sizes 结构&#xff0c;选择…

什么是GRACE CPU --- Grace CPU架构详解

深入详解GRACE CPU架构 NVIDIA Grace CPU 是 NVIDIA 开发的第一款数据中心 CPU。 通过将 NVIDIA 专业知识与 Arm 处理器、片上结构、片上系统 (SoC) 设计和弹性高带宽低功耗内存技术相结合&#xff0c;NVIDIA Grace CPU 从头开始构建&#xff0c;以创建世界上第一个超级芯片 用…

Spring控制反转(IoC)和依赖注入(DI)

Spring官网&#xff1a;spring.io1.spring 2.SprinMVC 3.Maven高级 4.SpringBoot 5.MyBatisPlus为什么要学Spring?简化开发&#xff0c;降低企业级开发的复杂度框架整合&#xff0c;高效整合其他技术&#xff0c;提高企业级应用开发与运行效率Spring 系统架构IOC&#xff08;I…