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;
}


相关文章
|
8天前
|
算法 C++
算法笔记:递归(c++实现)
算法笔记:递归(c++实现)
|
5天前
|
算法 前端开发 Linux
【常用技巧】C++ STL容器操作:6种常用场景算法
STL在Linux C++中使用的非常普遍,掌握并合适的使用各种容器至关重要!
32 10
|
1天前
|
机器学习/深度学习 算法 BI
机器学习笔记(一) 感知机算法 之 原理篇
机器学习笔记(一) 感知机算法 之 原理篇
|
7天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-2
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
7天前
|
算法 C++
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题-1
【数据结构与算法】:关于时间复杂度与空间复杂度的计算(C/C++篇)——含Leetcode刷题
|
8天前
|
编译器 C++
C++学习笔记(二开始学习C++)
C++学习笔记(二开始学习C++)
|
7天前
|
存储 算法 C++
【数据结构与算法】:带你手搓顺序表(C/C++篇)
【数据结构与算法】:带你手搓顺序表(C/C++篇)
|
15天前
|
存储 算法 Cloud Native
C++ bcrypt算法 字符串加密,亲测有效
C++ bcrypt算法 字符串加密,亲测有效
|
8天前
|
算法 C++
【c/c++算法】曼哈顿算法简单运用
【c/c++算法】曼哈顿算法简单运用
|
1天前
|
C++
C++一分钟之-类与对象初步
【6月更文挑战第20天】C++的类是对象的蓝图,封装数据和操作。对象是类的实例。关注访问权限、构造析构函数的使用,以及内存管理(深拷贝VS浅拷贝)。示例展示了如何创建和使用`Point`类对象。通过实践和理解原理,掌握面向对象编程基础。
29 2
C++一分钟之-类与对象初步