素筛

#include<iostream>
#include<cstdio>
#include<cmath>
#define max 10001
#define LL __int64
using namespace std;
int ISPrime(int a);
int Prime(int a);
int Prime_2(int a);
int main()
{
	int n;
	cin >> n;
	cout << ISPrime(n);
	return 0;
 }
//时间复杂度o(n) n为要晒选的数 
int ISPrime(int a) //方法一,利用一个数n,它是合数,那么一定存在小于sqrt(n)的因子 
{
	if(a <= 1)
		return 0;
	int bound = (int)sqrt(a) + 1; //防止精度出问题,加上一,多循环一次 
	for(int i=2;i<bound;i++)
	{
		if(a%i == 0) //可以被整出 
			return 0;
	}
	return 1;
}

//如一个数不是素数,那么一定存在一个小于它的素数因子。--注释1 
int Prime(int a) 
{
	int mark[max]={0};//用来记录没一个数对应的值:0为质数,1不是质数 
	int prime[max]={0};//用来存储质数 
	int index = 0;//记录有多少个质数 
	for(int i=0;i<max;i++)
	{
		if(mark[i]==1)
			continue;
		else
		{
			prime[index++] = i;//将质数存到数列 
			for(int j=i*i;j<max;j+=i)
			{
				mark[j] = 1;
			}
		}
	 }
	 return index;
}

//如一个数不是素数,那么一定存在一个小于它的素数因子。--注释1 
//Prime()的改良。 
int Prime_2(int a)
{
	int prime[max] = {0}; int mark[max] = {0};
	int index=0;
	prime[1] = 1;
	for(int i=1;i<max;i++)
	{
		if(!prime[i])
		{
			mark[++index] = i;
			for(LL j=(LL)i*i;j<max;j+=i)
			{
				prime[j]=1;
			}
		}
	}
	return index;
}
/*注释一 证明:
反证法:
对一个合数n,如果不存在一个质数因子,那么它的所有因子均不是质数,
设它的最小的因子为a,那么a也可以向下找到它的最小的因子b,那么接
着找下去,就会得到一个结果 不会存在质数,因为数都是合数。 
*/ 
///假设所有数都是质数,此时质数为0,合数为1 
int Prime_3(int a)
{
	int prime[max]={1};//所有数 
	int mark[max]={0};//存储筛选出来的质数 
	int num=0;
	for(int i=2;i<max;i++)
	{
		if(!prime[i])
			mark[num++] = i;//将对应的数赋值给数列 
			//关键处1,初始设为0,都会经过关键处1 
		for(LL j=0;j<num&&i*mark[j]<n;j++)
		{
			//j<num是为了只在当前有的质数范围内乘 
			prime[i*mark[j]]=1;
			//标记目前得到的素数的i倍为非素数 
			if(!(i%prime[j])) //关键处2 
				break;//此时prime[j]为最小质因子
				//------------- 注释二 
		}
	}
	return num;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值