acwing基础课——质数

news2024/11/26 6:18:53

由数据范围反推算法复杂度以及算法内容 - AcWing

常用代码模板4——数学知识 - AcWing

基本思想:

        首先,我们给出质数的定义,指在大于1的自然数中,除了1和该数自身外,无法被其他自然数整除的数。这里考虑三个问题:

(一)质数的判定—试除法

        我们很容易想到用暴力来做,从2遍历到数n,代码如下:

bool isPrime(int n)
{
    for(int i = 2; i <= n; i++)
    {
        if(n % i == 0) return false;
    }
    return true;
}

可以看出时间复杂度为O(n),那么当我们判断m个数是否为质数时复杂度就变成了O(n * m),容易超时,这时候我们就要去考虑优化了,数论这块内容主要考察的是对数学知识的掌握,我们可以发现质数的因数是成对出现的,即d | n(d能整除n),那么(n/d) | n , (例如:12%3=0  12%(12/3) =0)

 我们每次就只用枚举较小的那个因数即可,这样我们的时间复杂度就可以从O(n)降到O(sqrt(n))

866. 试除法判定质数 - AcWing题库

给定 n 个正整数 ai,判定每个数是否是质数。

输入格式

第一行包含整数 n。

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

输出格式

共 n 行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出 Yes,否则输出 No

数据范围

1≤n≤100,
1≤ai≤2^31−1

输入样例:

2
2
6

输出样例:

Yes
No
#include<iostream>

using namespace std;

int n;

bool is_prime(int x)
{
    if(x < 2) return false;
    
    for(int i = 2; i <= x / i; i++)
    {
        if(x % i == 0) return false;
//n/d n/n/d 12/3  12/12/3-> 12/4 质数的约数是成对出现的 变化一下就可以从O(n)优化到O(sqrt(n)
    }
    
    return true;
}

int main()
{
    cin>>n;
    
    while(n--)
    {
        int x;
        cin >> x;
        if(is_prime(x)) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    
    return 0;
}

(二)分解质因数——试除法

对于任何一个大于1的自然数 n,如果n不为质数,那么n可以唯一分解成有限个质数的乘积,即:

 

所以,我们可以扫描2~sqrt(N)之间的每一个整数i,若i能整除n,则从n中除掉所有的因子i,同时累计除去的i的个数,且当条件if(n % i == 0)成立时,i一定为n的一个质因子。这里我们的时间复杂度最坏情况为O^(sqrt(n)),而最好情况为O^(log(n)),比如当n为2的k次方时,一次就除尽了,一般情况下是优于试除法的效率。

867. 分解质因数 - AcWing题库

给定 n 个正整数 ai,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。

输入格式

第一行包含整数 n。

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

输出格式

对于每个正整数 ai,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。

每个正整数的质因数全部输出完毕后,输出一个空行。

数据范围

1≤n≤100,
2≤ai≤2×10^9

输入样例:

2
6
8

输出样例:

2 1
3 1

2 3
#include<iostream>

using namespace std;

int n;

//时间复杂度最坏情况为O^(sqrt(n)),最好情况为O^(log(n)),比如当n为2的k次方时,一次就除尽了。
void divide(int n)
{
    for(int i = 2; i <= n / i; i++)
    {
        if(n % i == 0) //满足这个条件那么i一定是质因子,将n看作几个质因数相乘
        {
            int s = 0;
            
            while(n % i == 0)
            {
                n /= i;
                s++;
            }
            
            cout << i << " " << s << endl; 
        }
    }
    
    if(n > 1) cout << n << " 1" << endl; 
//我们优化到只用循环sqrt(n)次,所以只用特判一下,如果n没有除尽说明还剩下一个大于sqrt(n)的质因子
//而且n肯定只包含一个大于sqrt(n)的质因子,因为如果有俩,他们的乘积就大于n了,这是不可能的
}

int main()
{
    cin>>n;
    
    while(n--)
    {
        int x;
        cin>>x;
        divide(x);
        puts("");
    }
    
    return 0;
}

(三)求质数个数(筛质数)——朴素筛法,埃及筛法和线性筛法

筛质数的核心思想就是,对于n个数,从2开始枚举,依次将其倍数删去,如果枚举到该数仍存在则该数一定为质数,因为例如一个数p,枚举到它时还存在,说明它不是2~p-1中任何数的倍数,即该数为质数。

 所以,很容易得到我们的朴素筛法,即循环2~n每次删掉当前数的倍数,分析时间复杂度,循环n-1次,每次循环n/i次,即n/2+n/3+.....+n/n -> n(ln n + c),即时间复杂度可看作(nlogn)

void get_primes(int n)
{
    for (int i = 2; i <= n; i++)
    {
        if (st[i]) continue;
        primes[cnt++] = i;
        for (int j = i + i; j <= n; j += i) st[j] = true;
    }
}

埃及筛法就是在朴素筛法的基础上,我们只用将质数的倍数删掉即可,因为一个合数可以写成几个质数的积,那么我们将所有质数的倍数删掉时,所有合数也被删掉了,这样可以将时间复杂度优化到O(nloglogn),可粗略看作O(n)。

void get_primes(int n)
{
    for (int i = 2; i <= n; i++)
    {
        if (!st[i])
        {
        primes[cnt++] = i;
        for (int j = i + i; j <= n; j += i)
            st[j] = true;
        }
    }
}

线性筛法,核心是每一个数n只会被它的最小质因子筛掉,我们扫描2~n,如果当前数没有被删掉,那么它就是质数,我们将其添加到质数数组里,在每次循环中,我们从小到大枚举每一个质数,当 i%pj == 0, pj定为i最小质因子,pj也定为pj*i最小质因子 ,当i%pj != 0, pj定小于i的所有质因子,所以pj也为pj*i最小质因子,这样我们就可以将以pj作为最小质因子的合数删去。对于任意一个合数x,假设pj为x的最小质因子,当i枚举到x / pj 时,我们就会将x删去,保证了每个数都会被遍历到,且if(i % primes[j] == 0) break;保证了在走完当前所有质数之前,一定会遇到i%primes[j]==0.所以不需要加判断j <= cnt的条件。

 

void get_primes(int n)
{
    for (int i = 2; i <= n; i++)
    {
        if (!st[i]) primes[cnt++] = i;
        for (int j = 0; primes[j] <= n / i; j++)
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0) break;
        }
    }
}

868. 筛质数 - AcWing题库

给定一个正整数 n,请你求出 1∼n 中质数的个数。

输入格式

共一行,包含整数 n。

输出格式

共一行,包含一个整数,表示 1∼n 中质数的个数。

数据范围

1≤n≤10^6

输入样例:

8

输出样例:

4
//朴素筛法
/*#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1000010;
int primes[N],cnt;
bool st[N];
int n;

void get_primes(int n)
{
    for(int i = 2; i <= n; i++)
    {
        if(!st[i]) primes[cnt++] = i;
        for(int j = i + i; j <= n; j += i) st[j] = true;
    }
}

int main()
{
    cin>>n;
    
    get_primes(n);
    
    cout << cnt;
    
    return 0;
}
*/

//埃及筛法
/*#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1000010;
int primes[N],cnt;
bool st[N];
int n;

void get_primes(int n)
{
    for(int i = 2; i <= n; i++)
    {
        if(!st[i])
        {
            primes[cnt++] = i;
            for(int j = i + i; j <= n; j += i) st[j] = true;
        }
    }
}

int main()
{
    cin>>n;
    
    get_primes(n);
    
    cout << cnt;
    
    return 0;
}
*/

//线性筛法
#include<iostream>
#include<algorithm>

using namespace std;

const int N = 1000010;
int primes[N],cnt;
bool st[N];
int n;

void get_primes(int n)
{
    for(int i = 2; i <= n; i++)
    {
        if(!st[i]) primes[cnt++] = i;
        for(int j = 0; primes[j] <= n / i; j++)
        {
            st[primes[j] * i] = true;
            if(i % primes[j] == 0) break;
        }
    }
}

int main()
{
    cin>>n;
    
    get_primes(n);
    
    cout << cnt;
    
    return 0;
}

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

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

相关文章

笔记-鼠标悬浮展示图标

鼠标悬浮展示图标 .primaryLink {color: primary-color-dark;}.primaryLink:hover {cursor: pointer;color: link-hover-color-dark;}.itemAction {display: none; }.itemMenu:hover .itemAction {display: block; }

【数据结构进阶】并查集

并查集 正如它的名字一样&#xff0c;并查集&#xff08;Union-Find&#xff09;就是用来对集合进行 合并&#xff08;Union&#xff09; 与 查询&#xff08;Find&#xff09; 操作的一种数据结构。 合并 就是将两个不相交的集合合并成一个集合。 查询 就是查询两个元素是否属…

链表常见OJ题汇总(持续更新)

目录前言一、移除链表中的元素&#xff08;多指针法&#xff09;二、反转链表&#xff08;多指针法&头插法&#xff09;三、链表的中间结点&#xff08;算数法和双指针法&#xff09;四、链表中的第K个结点&#xff08;算数法&双指针法&#xff09;五、合并两个有序链表…

vue 父子组件设置 scoped, 如何导致滚动条失效的

vue父组件的页面结构 // 调用子组件 <process-time-line :nodeArr"nodeArr"></process-time-line> 父组件的样式 <style lang"scss" scoped> ::-webkit-scrollbar {width: 0px;height: 0px;} </style>子组件的页面结构 <div …

学习C语言笔记:字符串和格式化输入/输出

学习内容&#xff1a;1.函数——strlen()&#xff1b;2.关键字——const&#xff1b;3.字符串&#xff1b;4..如何创建、存储字符串&#xff1b;5.如何使用strlen()函数获取字符串的长度&#xff1b;6.用C预处理器指令#define和ANSIC的const修饰符创建符号常量。与程序交互和使…

《Linux运维实战:Centos7.6基于docker-compose一键离线部署redis6.2.8之哨兵集群》

一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面向不通的客户安装我们的业务系统&#xff0c;而作为基础组件中的redis针对不同的客户环境需要多次部署哨兵集群&#xff0c;作为一个运维工程师&#xff0c;提升工作效率也是工作中的重要一环。所以我觉得有必要针对re…

(Java高级教程)第三章Java网络编程-第一节3:网络编程必备网络知识3之IP地址、端口号

文章目录一&#xff1a;网络传输基本流程&#xff08;1&#xff09;数据包&#xff08;2&#xff09;网络传输的基本流程&#xff08;3&#xff09;具体处理过程A&#xff1a;发送数据B&#xff1a;路由转发C&#xff1a;接受数据二&#xff1a;网络中的地址&#xff08;1&…

Elasticsearch-使用入门

_cat /_cat/nodes&#xff1a;查看所有节点 接口&#xff1a;GET http://192.168.177.134:9200/_cat/nodes /_cat/health&#xff1a;查看ES健康状况 接口&#xff1a;GET http://192.168.177.134:9200/_cat/health /_cat/master&#xff1a;查看主节点信息 接口&#xff1a;G…

【Azure 架构师学习笔记】-Azure Logic Apps(3)-演示1

本文属于【Azure 架构师学习笔记】系列。 本文属于【Azure Logic Apps】系列。 接上文【Azure 架构师学习笔记】-Azure Logic Apps&#xff08;2&#xff09;-组件介绍 前言 前面两篇文章大概介绍了一些理论知识&#xff0c;但是为用而学才是最重要的&#xff0c;所以接下来做…

word排版时如何保证每张图片大小一样?

问题描述 为了保证文档的美观性&#xff0c;在对图片进行排版时&#xff0c;最好保证图片的大小一致&#xff0c;尤其是多张图片组成一张大图时。 如果一张张图片调整大小&#xff0c;那真的是毫无技术含量的耗时工作。 解决方案 在这提出一种借助表格的解决办法。比如有4张…

Parasoft发布最广泛的MISRA规则覆盖-C/C++test最新版本正式上线!

作为拥有30多年自动化软件测试经验的全球领导者Parasoft宣布发布Parasoft C/Ctest的最新2022.2版本&#xff0c;支持MISRA C:2012修正案3和MISRA C 202x的草案版本。Parasoft针对C和C软件开发的统一、完全集成的测试解决方案的最新版本&#xff0c;帮助团队实现自动化静态分析和…

【java入门系列三】java基础-控制结构

学习记录&#x1f914;分支控制if-elseswitch分支接收字符for循环控制while循环do-while打印金字塔break终止-可以用label&#xff1a;表明continue与break类似return循环中表示直接退出方法(函数)&#xff0c;主方法直接结束字符串比较trick讨论总结谢谢点赞交流&#xff01;(…

外观模式

外观模式 1.外观模式介绍 1.外观模式&#xff08;Facade&#xff09;&#xff0c;也叫“过程模式&#xff1a;外观模式为子系统中的一组接口提供一个一致的界面&#xff0c;此模式定义了一个高层接口&#xff0c;这个接口使得这一子系统更加容易使用 2.外观模式通过定义一个一…

Linux(06)之获取内核代码

Linux(06)之获取内核代码 Author&#xff1a;OnceDay Date&#xff1a;2023年1月5日 漫漫长路&#xff0c;有人对你微笑过嘛… 参考文档&#xff1a; 《Linux内核设计和实现》 1.概述 linux内核的基本架构如下&#xff1a; 所以每个处理器运行的地方只有以下可能&#xf…

带你玩转指针——指针进阶(二)

上次我们说到了函数指针&#xff0c;对于函数指针大家还不太清楚的参考&#xff0c;指针进阶&#xff08;一&#xff09;http://t.csdn.cn/z5cjM函数指针数组数组是存放相同类型的空间&#xff0c;前面我们已经学习了指针数组int* arr[10] 每个元素是int*那么我们把函数的地址存…

grpc实现c++异步非阻塞stream

grpc实现c异步非阻塞stream 参考文章 Non-blocking single-threaded streaming C servergRPC C async api doc and sample codegrpc异步stream server端demo 序言 原来一直是用着同步阻塞的grpc stream。由于不想再创建新的线程来监听grpc stream的新消息了&#xff0c;所以就…

怎么提高程序设计能力?可以参考程序-设计原则,程序-设计模式

怎么提高程序设计能力&#xff1f; 简单说下我的方式方法&#xff1a; 【程序架构】 借鉴设计模式和设计原则 【程序业务】 多理解客户需求&#xff0c;理解后&#xff0c;做竞品逻辑分析&#xff0c;分析出其逻辑结构&#xff0c;和数据结构 &#xff1b; 再根据客户需求…

自己有工厂,怎样接外贸订单?

很多做外贸的小工厂和小型加工厂&#xff0c;除了传统的营销渠道外&#xff0c;也不知道如何做、才能接到外贸订单。小工厂想获得外贸订单&#xff0c;可通过以下7个方法&#xff1a;1、注册一些外贸B2B平台&#xff0c;发布产品&#xff0c;等待客户询盘外贸B2B平台太多了&…

商务车改装之奔驰威霆改装

今天来看看这台车的改装效果&#xff0c;首先外观改成GLS的一个包围。同时大灯换了一个三道杠的运动大灯。运动大灯加上包围&#xff0c;是不是时尚了很多。再来看看威霆内饰&#xff0c;白红相间的色彩搭配&#xff0c;仪表台换成一个大连屏的仪表台&#xff0c;带着飞机一样的…

4路DI开关检测计数器NPN/PNP输入,Modbus TCP协议,WiFi模块YL160频率测量 计数器

特点&#xff1a;● 4路开关量输入&#xff0c;支持NPN和PNP输入● DI每一路都可用作计数器或者频率测量● 支持Modbus TCP 通讯协议● 可以设置每转脉冲数用于转速测量● 内置网页功能&#xff0c;可以通过网页查询电平状态● 可以通过网页设定输出状态● 宽电源供电范围&…