c++算法学习笔记 (17) 质数

简介: c++算法学习笔记 (17) 质数

1.试除法判断某个数是否为质数

#include <iostream>
using namespace std;
const int N = 50005;
bool is_prime1(int n)
{ // 暴力写法:O(n)
    if (n < 2)
        return false;
    for (int i = 2; i < n; i++)
    {
        if (n % i == 0)
            return false;
    }
    return true;
}
// 优化,每次只枚举较小的一个约数
bool is_prime2(int n)
{ // O(根号n)
    if (n < 2)
        return false;
    for (int i = 2; i <= n / i; i++)
    {
        if (n % i == 0)
            return false;
    }
    return true;
}
int main()
{
 
    return 0;
}


2. 分解质因数

给定 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;
const int N = 50005;
void divide1(int n)
{
    for (int i = 2; i <= n; i++) // 底数一定为质数(因为从小到大枚举)
    {                            // 暴力 O(n)
        if (n % i == 0)
        {
            int s = 0;
            while (n % i == 0)
            {
                n /= i;
                s++;
            }
            cout << i << " " << s << endl; // 底数,指数
        }
    }
    cout << endl;
}
// 优化:n中最多只包含一个大于sqrt(n)的质因子(反证:如果有两个,则乘起来>n)
void divide2(int n)
{
    for (int i = 2; i <= n / i; i++)
    { // O(logn)~O(根号n)
        if (n % i == 0)
        {
            int s = 0;
            while (n % i == 0)
            {
                n /= i;
                s++;
            }
            cout << i << " " << s << endl; // 底数,指数
        }
    }
    if (n > 1)                         // 最后剩下的数要么为1,要么为大于sqrt(n)的质因子
        cout << n << " " << 1 << endl; // 特殊处理即可
    cout << endl;
}
int main()
{
    int n;
    cin >> n;
    while (n--)
    {
        int x;
        cin >> x;
        divide2(x);
    }
    return 0;
}

3. 筛质数

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

输入格式

共一行,包含整数 n。

输出格式

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

数据范围

1≤n≤10^6

输入样例:
8


输出样例:
4


#include <iostream>
using namespace std;
const int N = 1000010;
int primes[N], cnt;
bool st[N];
void get_primes1(int n)
{ // O(lnn)
    for (int i = 2; i <= n; i++)
    {
        if (st[i] == 0)
        {
            primes[cnt++] = i; // 存质数
        }
 
        for (int j = i + i; j <= n; j += i)
        {
            st[j] = true; // 将i的倍数删去
        }
    }
}
// 优化:不必枚举2~p-1,只需枚举里面的质数
void get_primes2(int n) // 埃氏筛:原理:在朴素筛法的过程中只用质数项去筛.
{                       // O(nloglogn)
    for (int i = 2; i <= n; i++)
    {
        if (st[i] == 0)
        {
            primes[cnt++] = i;
            for (int j = i + i; j <= n; j += i)
            {
                st[j] = true; // 将i的倍数删去
            }
        }
    }
}
// 线性筛法
void get_primes3(int n)
{ // 原理:1~n之内的任何一个合数一定会被筛掉,而且筛的时候只用最小质因子来筛,
    // 然后每一个数都只有一个最小质因子,因此每个数都只会被筛一次,因此线性筛法是线性的.
    for (int i = 2; i <= n; i++)
    {
        if (st[i] == 0)
        {
            primes[cnt++] = i;
        }
        for (int j = 0; primes[j] <= n / i; j += i)
        {
            st[primes[j] * i] = true;
            if (i % primes[j] == 0)
                break;
        }
    }
}
int main()
{
    int n;
    cin >> n;
    get_primes2(n);
    cout << cnt << endl;
    return 0;
}


相关文章
|
19天前
|
存储 算法 C++
高精度算法(加、减、乘、除,使用c++实现)
高精度算法(加、减、乘、除,使用c++实现)
257 0
高精度算法(加、减、乘、除,使用c++实现)
|
17天前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
14 0
|
26天前
|
存储 算法 决策智能
【算法】博弈论(C/C++)
【算法】博弈论(C/C++)
|
26天前
|
存储 算法 C++
【算法】哈希映射(C/C++)
【算法】哈希映射(C/C++)
|
26天前
|
机器学习/深度学习 人工智能 算法
【算法】最长公共子序列(C/C++)
【算法】最长公共子序列(C/C++)
|
26天前
|
人工智能 算法 BI
一篇带你速通差分算法(C/C++)
一篇带你速通差分算法(C/C++)
|
26天前
|
人工智能 算法 C++
一篇带你速通前缀和算法(C/C++)
一篇带你速通前缀和算法(C/C++)
|
26天前
|
存储 算法 C++
弗洛伊德(Floyd)算法(C/C++)
弗洛伊德(Floyd)算法(C/C++)
|
26天前
|
存储 算法 程序员
迪杰斯特拉(Dijkstra)算法(C/C++)
迪杰斯特拉(Dijkstra)算法(C/C++)
|
26天前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)