线性筛素数

本文介绍了一个简单的质数查询算法,该算法能够在给定范围内判断任意数字是否为质数,并通过循环遍历的方式进行验证。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

如题,给定一个范围N,你需要处理M个某数字是否为质数的询问(每个数字均在范围1-N内)

输入输出格式

输入格式:

第一行包含两个正整数N、M,分别表示查询的范围和查询的个数。

接下来M行每行包含一个不小于1且不大于N的整数,即询问该数是否为质数。

输出格式:

输出包含M行,每行为Yes或No,即依次为每一个询问的结果。

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int n,m,s,t;
int search(int m)
{
	if(m==1||m==0)
	{
		return 1;
	}
	if(m==2)
	{
		return 0;
	}
	for(register int b=2;b<=sqrt(m);b++)
	{
		if(s%b==0)
		{
			return 1;
		}
	}
}
int main()
{
	cin>>n>>m;
	for(register int a=1;a<=m;a++)
	{
		cin>>s;
		t=search(s);
		if(t==1)
		{
			cout<<"No"<<endl;
		}
		else
		{
			cout<<"Yes"<<endl;
		}
		t=0;
	}
}


线性筛法(也称为欧拉筛法)是一种高效的求解素数的方法,其时间复杂度为 O(n),适用于大规模数据的素数筛选。相较于埃拉托斯特尼筛法(埃式筛),线性筛法通过避免重复标记来提高效率,确保每个合数只被其最小的质因数筛除一次。 以下是一个使用 C 语言实现线性筛法求素数的完整示例代码: ```c #include <stdio.h> #include <stdlib.h> #define MAXN 1000000 // 定义最大范围,可以根据需求调整 int main() { int n = 100000; // 设置上限,也可以通过输入获取 int *is_prime = (int *)malloc((n + 1) * sizeof(int)); // 用于标记是否素数 int *primes = (int *)malloc(n * sizeof(int)); // 用于存储素数 int count = 0; // 记录素数个数 // 初始化标记数组 for (int i = 2; i <= n; i++) { is_prime[i] = 1; // 初始假设所有数都是素数 } // 线性筛法核心逻辑 for (int i = 2; i <= n; i++) { if (is_prime[i]) { primes[count++] = i; // 如果是素数,加入素数表 } // 遍历当前素数表中的素数,并标记合数 for (int j = 0; j < count && i * primes[j] <= n; j++) { is_prime[i * primes[j]] = 0; // 标记为非素数 if (i % primes[j] == 0) { break; // 保证每个合数只被其最小的质因数筛除 } } } // 输出所有素数 printf("Prime numbers up to %d:\n", n); for (int i = 0; i < count; i++) { printf("%d ", primes[i]); } printf("\n"); // 释放内存 free(is_prime); free(primes); return 0; } ``` ### 代码说明: 1. **初始化**:创建两个数组,`is_prime` 用于标记每个数是否素数,`primes` 用于存储筛选出的素数。 2. **外层循环**:从 2 开始遍历到 n,如果当前数未被标记为非素数,则将其加入素数数组。 3. **内层循环**:利用当前素数数组中的素数,对当前数的倍数进行标记。关键点在于 `i % primes[j] == 0` 的判断,确保每个合数只被其最小的质因数筛除一次。 4. **输出结果**:最后输出所有筛选出的素数。 ### 优化特性: - 每个合数只会被其最小的质因数筛除一次,避免了重复操作。 - 时间复杂度为 O(n),适合处理大规模数据。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值