题目链接

判断质数

题目描述

给定一个正整数 ,请判断 是否为质数。 质数的定义是:在大于 1 的自然数中,除了 1 和它本身以外不再有其他因数的自然数。

解题思路

判断一个数 是否为质数,最直观的方法是尝试用从 的所有整数去除 ,如果都不能整除,那么 就是质数。但是这种方法效率较低。我们可以对其进行优化。

核心思想:试除法优化

一个重要的数学性质是:如果一个数 有一个因数 ,那么它必然有另一个因数 。这两个因数中,必然有一个不大于 ,另一个不小于

  • 例如,对于
    • 因数 对应因数 ,其中
    • 因数 对应因数 ,其中
    • 因数 对应因数 ,其中
    • 因数 对应因数 ,其中

这意味着,如果 不是质数,它必定存在一个小于或等于 的因数。反之,如果我们检查了从 的所有整数,都不能整除 ,那么 就不可能再有其他因数了(除了1和它自身),因此 必定是质数。

算法步骤

  1. 处理特殊情况
    • 如果 ,根据定义,它不是质数。
  2. 试除
    • 开始,循环直到 (这等价于 ,但避免了浮点数计算,更高效且精确)。
    • 在循环中,检查 是否能被 整除(即 n % i == 0)。
    • 如果能整除,说明 有一个小于自身的因数 ,因此 不是质数,可以直接返回 No
  3. 最终判断
    • 如果循环正常结束,没有找到任何能整除 的数,说明 是质数,返回 Yes

代码

#include <iostream>
#include <cmath>

using namespace std;

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

int main() {
    long long n;
    cin >> n;
    if (is_prime(n)) {
        cout << "Yes\n";
    } else {
        cout << "No\n";
    }
    return 0;
}
import java.util.Scanner;

public class Main {
    public static boolean isPrime(long n) {
        if (n <= 1) {
            return false;
        }
        for (long i = 2; i * i <= n; i++) {
            if (n % i == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long n = sc.nextLong();
        if (isPrime(n)) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    }
}
import math

def is_prime(n):
    if n <= 1:
        return False
    # 遍历到 int(sqrt(n)) + 1 即可
    for i in range(2, int(math.sqrt(n)) + 1):
        if n % i == 0:
            return False
    return True

def solve():
    n = int(input())
    if is_prime(n):
        print("Yes")
    else:
        print("No")

solve()

算法及复杂度

  • 算法:试除法
  • 时间复杂度:我们需要循环大约 次来检查是否存在因数。因此,时间复杂度为
  • 空间复杂度:我们只使用了少数几个变量来存储中间值,所以空间复杂度为