[アルゴリズムの基礎]AcWing868.ふるい素数(詳細)

ここに画像の説明を挿入


トピックの説明

トピックリンク
ここに画像の説明を挿入

アイデア1

アイデア1(最も簡単なアプローチ):各数値の倍数を徐々に除外して、乾燥後、残りが素数になるようにします。たとえば、11が削除されない場合、1〜10は11の約数ではないことを意味します。 11の約数は1とそれ自体だけなので、11は素数です。
ここに画像の説明を挿入

時間計算量O(n * logn)
ここに画像の説明を挿入

#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 = i + i; j <= n; j += i) {
    
    
            st[j] = true;
        }
    }
}

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

アイデア2:線形ふるい法[合成数をふるいにかけるために最小の素因数を使用する]

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int primes[N], cnt;
bool st[N];//质数则为false  否则为true

// 朴素做法
// 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;//筛掉后面它的倍数
//         }
//     }
// }

void get_primes(int n) {
    
    
    for (int i = 2; i <= n; i++) {
    
    
        if(!st[i]) {
    
    //如果是质数的话,就加入的质数表里面去  
            primes[cnt++] = i;
        }   
       // primes[j] <= n / i == primes[j] * i <= n,而primes[j] * i就是所有要筛除的合数
        for (int j = 0; primes[j] <= n / i; j ++) {
    
    //枚举质数
            st[primes[j] * i] = true;// 合数 = i * pj (pj为小于 i 的最小质因子 
            if(i % primes[j] == 0) {
    
    
                break; //primes[j]一定是i的最小质因子 
            }//举个例子,对于一个数9,9*2=18将18标记为合数,循环继续;9*3=27将27标记为合数,
            //此时发现9%3=0,循环退出。如果将循环继续下去会出现筛除9*5=45的情况,
            //而45=15*3,在15时会被在筛去一次,故不可行
        }
    }
}
int main () {
    
    
    int n;
    cin >> n;
    get_primes(n);
    cout << cnt << endl;
    return 0;
}


おすすめ

転載: blog.csdn.net/weixin_49486457/article/details/123976183