AcWing 866. 试除法判定质数

246 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第19天,点击查看活动详情

AcWing 866. 试除法判定质数

给定 n 个正整数 ai,判定每个数是否是质数。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含一个正整数 ai。

输出格式

共 n 行,其中第 i 行输出第 i 个正整数 ai 是否为质数,是则输出 Yes,否则输出 No

数据范围

1 ≤ n ≤ 100,
1 ≤ ai ≤ 2^31−1

输入样例:

2
2
6

输出样例:

Yes
No

思路

试除法

暴力运算
质数是指在大于1的自然数中,除了1和它本身以外不再有其他的自然数。
时间复杂度为O(n)

bool is_prime(int x) {
    if (x < 2) return false; //质数的定义,2是最小的质数,小于2的所有数字都不是质数
    for(int i = 2;i < x;i++){ //暴力循环试除判断,从最小的质数开始枚举到下 x - 1
        if(x % i == 0)return false;//如果当前数字可以被整除,说明这个数字不是质数
    }
    return true;
}

暴力代码

#include<iostream>
using namespace std;
bool is_prime(int x) {
    if (x < 2) return false;
    for(int i = 2;i < x;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)) cout << "Yes" << endl;
        else cout << "No" << endl;
    }
    return 0;
}

优化思路

一个数的因数都是成对出现的:例如12的因数有 3 和 4 , 2 和 6

所以我们可以只枚举较小的那一个,即根号x,假设较小的为d,较大的为n/d;

优化后时间复杂度为O(sqrt(n))

优化写法一

缺点每次循环都会调用sqrt函数

bool is_prime(int x){
    if(x < 2) return false; 
    for(int i = 2;i <= sqrt(x);i ++){ //优化部分
        if(x % i == 0){ 
            return false; 
        }
    }
    return true; 
}

优化写法二

缺点:i * i 的值会容易溢出超出int的范围,需要使用long

bool is_prime(long x){
    if (x < 2) return false;
    for (long i = 2; i * i<= x; i ++ )
        if (x % i == 0)
            return false;
    return true;
}

优化写法三

bool is_prime(int x){
    if(x < 2) return false; 
    for(int i = 2;i <= x / i;i ++){ //优化部分
        if(x % i == 0){ 
            return false; 
        }
    }
    return true; //返回是
}

试除法判定质数 —— 模板题 AcWing 866. 试除法判定质数

bool is_prime(int x){
    if (x < 2) return false;
    for (int i = 2; i <= x / i; i ++ )
        if (x % i == 0)
            return false;
    return true;
}