GESPC++考试五级语法知识(二、埃氏筛与线性筛)课后习题

🌟《素数筛法10道经典训练题》


第一题:输出1~n所有素数(埃氏筛基础题)

1、🏰故事

素数王国要发布一份 素数名单

(1)输入一个数字 n,请输出:

复制代码
1~n 所有素数

(2)输入

复制代码
30

(3)输出

复制代码
2 3 5 7 11 13 17 19 23 29

2、思路

(1)使用 埃氏筛


(2)步骤:

1 初始化全部为素数

2 从2开始

3 删除倍数


3、参考代码

复制代码
#include <iostream>
using namespace std;

const int N = 1000000;
bool isPrime[N];

int main()
{
    int n;
    cin>>n;

    for(int i=2;i<=n;i++)
        isPrime[i]=true;

    for(int i=2;i*i<=n;i++)
    {
        if(isPrime[i])
        {
            for(int j=i*i;j<=n;j+=i)
                isPrime[j]=false;
        }
    }

    for(int i=2;i<=n;i++)
        if(isPrime[i])
            cout<<i<<" ";
}

第二题:统计素数个数

1、🏰故事

(1)国王想知道:

复制代码
1~n 一共有多少个素数

(2)输入

复制代码
20

(3)输出

复制代码
8

(4)因为

复制代码
2 3 5 7 11 13 17 19

数一数,一共是8个


2、思路

筛素数

统计数量


3、参考代码

复制代码
#include <iostream>
using namespace std;

const int N = 1000000;
bool isPrime[N];

int main()
{
    int n;
    cin>>n;

    for(int i=2;i<=n;i++)
        isPrime[i]=true;

    for(int i=2;i*i<=n;i++)
        if(isPrime[i])
            for(int j=i*i;j<=n;j+=i)
                isPrime[j]=false;

    int cnt=0;

    for(int i=2;i<=n;i++)
        if(isPrime[i])
            cnt++;

    cout<<cnt;
}

第三题:判断多个数字是否为素数

1、🏰故事

(1)城门守卫需要检查很多数字。

输入 t个数字,判断每个是不是素数。


(2)输入

复制代码
5
2 4 7 9 11

(3)输出

复制代码
Yes
No
Yes
No
Yes

2、思路

先筛到 最大值

再查询。


3、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;
bool isPrime[N];

int main()
{
    int t;
    cin>>t;

    int a[1000];
    int mx=0;

    for(int i=0;i<t;i++)
    {
        cin>>a[i];
        mx=max(mx,a[i]);
    }

    for(int i=2;i<=mx;i++)
        isPrime[i]=true;

    for(int i=2;i*i<=mx;i++)
        if(isPrime[i])
            for(int j=i*i;j<=mx;j+=i)
                isPrime[j]=false;

    for(int i=0;i<t;i++)
    {
        if(isPrime[a[i]])
            cout<<"Yes\n";
        else
            cout<<"No\n";
    }
}

第四题:输出第k个素数(线性筛)

1、🏰故事

数学家问:

复制代码
第1000个素数是多少?

2、思路

使用 线性筛

记录素数数组。


3、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;

int prime[N];
bool vis[N];

int main()
{
    int n;
    cin>>n;

    int cnt=0;

    for(int i=2;i<N;i++)
    {
        if(!vis[i])
            prime[cnt++]=i;

        for(int j=0;j<cnt && i*prime[j]<N;j++)
        {
            vis[i*prime[j]]=true;

            if(i%prime[j]==0)
                break;
        }

        if(cnt>=n)
            break;
    }

    cout<<prime[n-1];
}

第五题:求1~n所有素数的和

1、🏰故事

(1)数学家问:

1~n所有素数的和是多少?

(2)输入

复制代码
10

(2)输出

复制代码
17

(3)因为

复制代码
2+3+5+7=17

2、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;

bool isPrime[N];

int main()
{
    int n;
    cin>>n;

    for(int i=2;i<=n;i++)
        isPrime[i]=true;

    for(int i=2;i*i<=n;i++)
        if(isPrime[i])
            for(int j=i*i;j<=n;j+=i)
                isPrime[j]=false;

    long long sum=0;

    for(int i=2;i<=n;i++)
        if(isPrime[i])
            sum+=i;

    cout<<sum;
}

第六题:输出区间内素数

1、🏰故事

(1)数学家问:

输入一个区间,输出区间内的所有素数。


(2)输入:

复制代码
L R

(3)输出

复制代码
L~R 的所有素数

2、输入

复制代码
10 30

输出

复制代码
11 13 17 19 23 29

3、思路

筛到 R


4、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;

bool isPrime[N];

int main()
{
    int L,R;
    cin>>L>>R;

    for(int i=2;i<=R;i++)
        isPrime[i]=true;

    for(int i=2;i*i<=R;i++)
        if(isPrime[i])
            for(int j=i*i;j<=R;j+=i)
                isPrime[j]=false;

    for(int i=L;i<=R;i++)
        if(isPrime[i])
            cout<<i<<" ";
}

第七题:统计区间素数数量

1、🏰故事

(1)数学家问:

输入一个区间,输出区间内的所有素数的数量。


(2)输入

复制代码
L R

(3)输出

复制代码
区间素数数量

2、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;

bool isPrime[N];

int main()
{
    int L,R;
    cin>>L>>R;

    for(int i=2;i<=R;i++)
        isPrime[i]=true;

    for(int i=2;i*i<=R;i++)
        if(isPrime[i])
            for(int j=i*i;j<=R;j+=i)
                isPrime[j]=false;

    int cnt=0;

    for(int i=L;i<=R;i++)
        if(isPrime[i])
            cnt++;

    cout<<cnt;
}

第八题:输出前n个素数(线性筛)


1、🏰故事

(1)数学家问:

输入数字n,输出从第一个到第n个素数。


(2)输入

复制代码
10

(3)输出

复制代码
2 3 5 7 11 13 17 19 23 29

2、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;

int prime[N];
bool vis[N];

int main()
{
    int n;
    cin>>n;

    int cnt=0;

    for(int i=2;i<N;i++)
    {
        if(!vis[i])
            prime[cnt++]=i;

        for(int j=0;j<cnt && i*prime[j]<N;j++)
        {
            vis[i*prime[j]]=true;

            if(i%prime[j]==0)
                break;
        }

        if(cnt>=n)
            break;
    }

    for(int i=0;i<n;i++)
        cout<<prime[i]<<" ";
}

第九题:判断哥德巴赫猜想

1、🏰故事

(1)数学家问:

输入任意大于2的偶数,将它分为两个素数的和


(2)输入:

复制代码
n (偶数)

(3)找两个素数:

复制代码
p + q = n

(4)输入

复制代码
20

(5)输出

复制代码
3 17

2、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;

bool isPrime[N];

int main()
{
    int n;
    cin>>n;

    for(int i=2;i<=n;i++)
        isPrime[i]=true;

    for(int i=2;i*i<=n;i++)
        if(isPrime[i])
            for(int j=i*i;j<=n;j+=i)
                isPrime[j]=false;

    for(int i=2;i<=n;i++)
    {
        if(isPrime[i] && isPrime[n-i])
        {
            cout<<i<<" "<<n-i;
            break;
        }
    }
}

第十题:统计每个数的最小质因数(线性筛进阶)

1、🏰故事

(1)数学家问:

给你一个数字n,输出从2~n它的最小因数

这题是 线性筛的优势题


(2)输入

复制代码
10

(3)输出

复制代码
2:2
3:3
4:2
5:5
6:2
7:7
8:2
9:3
10:2

2、参考代码

复制代码
#include <iostream>
using namespace std;

const int N=1000000;

int prime[N];
int minp[N];
bool vis[N];

int main()
{
    int n;
    cin>>n;

    int cnt=0;

    for(int i=2;i<=n;i++)
    {
        if(!vis[i])
        {
            prime[cnt++]=i;
            minp[i]=i;
        }

        for(int j=0;j<cnt && i*prime[j]<=n;j++)
        {
            vis[i*prime[j]]=true;

            minp[i*prime[j]]=prime[j];

            if(i%prime[j]==0)
                break;
        }
    }

    for(int i=2;i<=n;i++)
        cout<<i<<":"<<minp[i]<<endl;
}

🌟10题知识总结

题目 使用筛法
输出素数 埃氏筛
统计素数 埃氏筛
多次查询 埃氏筛
第k个素数 线性筛
素数求和 埃氏筛
区间素数 埃氏筛
区间统计 埃氏筛
前n素数 线性筛
哥德巴赫 埃氏筛
最小质因数 线性筛

🎯 最重要经验

比赛中:

1、埃氏筛

适合:

复制代码
快速得到所有素数

2、线性筛

适合:

复制代码
记录素数表
记录最小质因数
复杂数论

相关推荐
Old Uncle Tom5 小时前
OpenClaw 记忆系统 -- 记忆预加载
java·数据结构·算法·agent
会编程的土豆5 小时前
洛谷题单入门1 顺序结构
数据结构·算法·golang
生信碱移5 小时前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
智者知已应修善业6 小时前
【51单片机中的打飞机设计】2023-8-25
c++·经验分享·笔记·算法·51单片机
智者知已应修善业8 小时前
【51单片机按键调节占空比3位数码管显示】2023-8-24
c++·经验分享·笔记·算法·51单片机
.5489 小时前
## Sorting(排序算法)
python·算法·排序算法
wuweijianlove9 小时前
算法的平均复杂度建模与性能回归分析的技术7
算法·数据挖掘·回归
子琦啊9 小时前
【算法复习】字符串 | 两个底层直觉,吃透高频题
linux·运维·算法
code_pgf10 小时前
Octo 算法详解-开源通用机器人策略模型技术报告
算法·机器人·开源
嘻嘻哈哈樱桃11 小时前
牛客经典101题题解集--动态规划
java·数据结构·python·算法·职场和发展·动态规划