文章目录

  • 一、质数
  • 二、质数的判定——试除法
  • 1. 实现思路
  • 2. 实现代码
  • 三、分解质因数——试除法
  • 1. 实现思路
  • 2. 实现代码
  • 四、筛质数
  • 1. 朴素筛法
  • 1.1 实现思路
  • 1.2 实现代码
  • 2. 线性筛法
  • 2.1 实现思路
  • 2.2 实现代码


一、质数

  • 质数又称素数。一个大于 什么是javascrip 什么是质数_c++ 的自然数,除了 什么是javascrip 什么是质数_c++
  • 质数具有如下性质:
  • (1) 质数 什么是javascrip 什么是质数_c++_03 的约数只有两个:什么是javascrip 什么是质数_c++什么是javascrip 什么是质数_c++_03
  • (2) 初等数学基本定理:任一大于 什么是javascrip 什么是质数_c++
  • (3) 质数的个数是无限的。
  • (4) 若 什么是javascrip 什么是质数_c++_07 为正整数,在 什么是javascrip 什么是质数_算法_08什么是javascrip 什么是质数_质因数_09
  • (5) 所有大于 什么是javascrip 什么是质数_算法_10 的质数中,个位数只有 什么是javascrip 什么是质数_质因数_11

二、质数的判定——试除法

题目描述

给定 什么是javascrip 什么是质数_c++_12 个正整数 什么是javascrip 什么是质数_c++_13,判定每个数是否是质数。

输入格式

第一行包含整数 什么是javascrip 什么是质数_c++_12
接下来 什么是javascrip 什么是质数_c++_12 行,每行包含一个正整数 什么是javascrip 什么是质数_c++_13

输出格式

什么是javascrip 什么是质数_c++_12 行,其中第 什么是javascrip 什么是质数_算法_18 行输出第 什么是javascrip 什么是质数_算法_18 个正整数 什么是javascrip 什么是质数_c++_13 是否为质数,是则输出 Yes,否则输出 No

数据范围

什么是javascrip 什么是质数_算法_21
什么是javascrip 什么是质数_算法_22

输入样例

2
2
6

输出样例

Yes No

具体实现

1. 实现思路

  • 暴力写法:可以从质数的常规定义出发,首先判断这个数是不是大于等于 2 的,然后判断在 2 到这个数之间是否还有别的约数,如果没有,那么这个数就是质数,反之就不是质数。该暴力写法的时间复杂度是 什么是javascrip 什么是质数_c++_23
  • 对上述暴力写法进行优化时,需要利用到质数的一个性质。
  • 什么是javascrip 什么是质数_c++_24 可以整除 什么是javascrip 什么是质数_c++_07 时,显然,什么是javascrip 什么是质数_算法_26 也可以整除 什么是javascrip 什么是质数_c++_07。例如,当 什么是javascrip 什么是质数_什么是javascrip_28 时,什么是javascrip 什么是质数_算法_29什么是javascrip 什么是质数_c++_30 的约数,什么是javascrip 什么是质数_c++_31 也是 什么是javascrip 什么是质数_c++_30
  • 因此,在我们枚举的过程中,只需要枚举其中较小的一个即可,优化过后的时间复杂度是 什么是javascrip 什么是质数_质因数_33

2. 实现代码

#include <bits/stdc++.h>

using namespace std;

bool is_prime(int x)
{
    //判断这个数是否大于等于 2 
    if (x < 2)
    {
        return false;
    }
    //判断是否还有别的约束
    for (int i = 2; i <= x / i; i ++ )
    {
        if (x % i == 0)
        {
            return false;
        }
    }
    return true;
}

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

    while (n -- )
    {
        int x;
        cin >> x;
        if (is_prime(x))
        {
            puts("Yes");
        }
        else 
        {
            puts("No");
        }
    }

    return 0;
}

三、分解质因数——试除法

题目描述

给定 什么是javascrip 什么是质数_c++_12 个正整数 什么是javascrip 什么是质数_c++_13,将每个数分解质因数,并按照质因数从小到大的顺序输出每个质因数的底数和指数。

输入格式

第一行包含整数 什么是javascrip 什么是质数_c++_12
接下来 什么是javascrip 什么是质数_c++_12 行,每行包含一个正整数 什么是javascrip 什么是质数_c++_13

输出格式

对于每个正整数 什么是javascrip 什么是质数_c++_13,按照从小到大的顺序输出其分解质因数后,每个质因数的底数和指数,每个底数和指数占一行。
每个正整数的质因数全部输出完毕后,输出一个空行。

数据范围

什么是javascrip 什么是质数_算法_40
什么是javascrip 什么是质数_开发语言_41

输入样例

2
6
8

输出样例

2 1
3 1
(空行)
2 3
(空行)

具体实现

1. 实现思路

  • 我们需要注意的是,质因数的底数必须是质数。
  • 暴力写法:从小到大枚举 什么是javascrip 什么是质数_c++_07 的所有质因数,如果 什么是javascrip 什么是质数_c++_07什么是javascrip 什么是质数_算法_44 等于 什么是javascrip 什么是质数_算法_45,就求出 什么是javascrip 什么是质数_算法_44
void divide(int x)
{
    for (int i = 2; i <= x; i ++ )
    {
        if (x % i == 0) //i一定是质数
        {
            int s = 0;
            while (x % i == 0) 
            {
                x /= i;
                s ++ ;
            }
            cout << i << ' ' << s << endl;
        }
    }
}
  • 随后在对 什么是javascrip 什么是质数_c++_07 进行是否大于 什么是javascrip 什么是质数_c++
  • 对上述写法进行优化,我们需要使用质数的如下性质。
  • 什么是javascrip 什么是质数_算法_49 的质因子最多只包含一个大于 什么是javascrip 什么是质数_c++_50 的质数。如果有两个,这两个因子的乘积就会大于 什么是javascrip 什么是质数_算法_49,矛盾。
  • 然后,我们 什么是javascrip 什么是质数_算法_44什么是javascrip 什么是质数_什么是javascrip_53 遍历到 什么是javascrip 什么是质数_c++_50。 用 什么是javascrip 什么是质数_什么是javascrip_55,如果余数为 什么是javascrip 什么是质数_算法_45,则 什么是javascrip 什么是质数_算法_44
  • 什么是javascrip 什么是质数_什么是javascrip_58 表示质因子 什么是javascrip 什么是质数_算法_44 的指数,什么是javascrip 什么是质数_质因数_60什么是javascrip 什么是质数_算法_45,则 什么是javascrip 什么是质数_开发语言_62什么是javascrip 什么是质数_算法_63
  • 最后检查是否有大于 什么是javascrip 什么是质数_c++_50
  • 时间复杂度便会从 什么是javascrip 什么是质数_c++_23 降低到 什么是javascrip 什么是质数_质因数_33

2. 实现代码

#include <bits/stdc++.h>

using namespace std;

void divide(int x)
{
    for (int i = 2; i <= x / i; i ++ )
    {
        if (x % i == 0) //i一定是质数
        {
            int s = 0;
            while (x % i == 0) 
            {
                x /= i;
                s ++ ;
            }
            cout << i << ' ' << s << endl;
        }
    }
    if (x > 1)
    {
        cout << x << ' ' << 1 << endl;
    }
    cout << endl;
}

int main()
{
    int n;
    cin >> n;
    while (n -- )
    {
        int x;
        cin >> x;
        divide(x);
    }

    return 0;
}

四、筛质数

题目描述

给定一个正整数 什么是javascrip 什么是质数_c++_12,请你求出 什么是javascrip 什么是质数_什么是javascrip_68

输入格式

共一行,包含整数 什么是javascrip 什么是质数_c++_12

输出格式

共一行,包含一个整数,表示 什么是javascrip 什么是质数_什么是javascrip_68

数据范围

什么是javascrip 什么是质数_质因数_71

输入样例

8

输出样例

4

具体实现

1. 朴素筛法

1.1 实现思路

  • 首先,我们将所有的数放入一个数组当中,然后从前往后观察,依次将每一个数的倍数删除掉。
  • 经过这样筛选过后,剩下的数就都是质数。

1.2 实现代码

#include <bits/stdc++.h>

using namespace std;

const int N= 1000010;

//cnt表示质数的个数
int primes[N], cnt;
bool st[N];

void get_primes(int n)
{
    for (int i = 2; i <= n; i ++ )
    {
        if (st[i])
        {
            //跳出本次循环
            continue;
        }
        //primes[]数组存储质数
        primes[cnt ++ ] = i;
        //去除倍数
        for (int j = i + i; j <= n; j += i)
        {
            st[j] = true;
        }
    }
}

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

    get_primes(n);

    cout << cnt << endl;

    return 0;
}

2. 线性筛法

2.1 实现思路

  • 算法核心:什么是javascrip 什么是质数_c++_07
  • 什么是javascrip 什么是质数_c++_07 为一个合数的时候,如果 什么是javascrip 什么是质数_算法_44什么是javascrip 什么是质数_什么是javascrip_75
  • 判断 什么是javascrip 什么是质数_算法_76什么是javascrip 什么是质数_质因数_77 一定是 什么是javascrip 什么是质数_算法_44 的最小质因子,什么是javascrip 什么是质数_质因数_77 也一定是 什么是javascrip 什么是质数_质因数_80
  • 判断 什么是javascrip 什么是质数_c++_81, 什么是javascrip 什么是质数_质因数_77 一定小于 什么是javascrip 什么是质数_算法_44 的所有质因子,什么是javascrip 什么是质数_质因数_77 也一定是 什么是javascrip 什么是质数_质因数_80
  • 于一个合数 什么是javascrip 什么是质数_算法_49,假设 什么是javascrip 什么是质数_质因数_77什么是javascrip 什么是质数_算法_49 的最小质因子,当 什么是javascrip 什么是质数_算法_44 枚举到 什么是javascrip 什么是质数_开发语言_90

2.2 实现代码

#include <bits/stdc++.h>

using namespace std;

const int N= 1000010;

int primes[N], cnt;
bool st[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)  //primes[j]一定是i的最小质因子
            {
                break;
            }
        }
    }
}

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

    get_primes(n);

    cout << cnt << endl;

    return 0;
}