`
plussai
  • 浏览: 89199 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

筛法打素数表---zoj_1951

阅读更多

          筛法打素数表是一种高效的打表方法,体做法是:先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。c这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。需要注意的是,选取质数的时候,循环只需到sqrt(n)就可以。

          与之前的简单打表相比,来分析一个两种方法的效率。

          先看一下简单方法,对于每个需要判断的整数i,最多需要做sqrt(i)次求模的操作,因此算法的效率为sqrt(3)+sqrt(4)+sqrt(5)+sqrt(6)+sqrt(7).......+sqrt(N)

          再分析一下筛法,对于sqrt(N)以内的素数i,做N/i次筛选操作,因此我们可以看到次算法的效率为N/2+N/3+N/5+N/7+N/11+.......+N/k(K是小于sqrt(N)的最大素数)

          简单的数值分析计算一下上面的2个级数,可以看到后者明显小于前者

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int const maxm=1000001;
int prime[maxm];
void sievePrime()
{
	for(int i=0;i<maxm;i++)
		prime[i]=1;
	prime[0]=0;
	prime[1]=0;
	int max=sqrt(maxm*1.0);
	for(int i=2;i<=max;i++)
	{
		if(prime[i])
		for(int j=i+i;j<maxm;j=j+i)
		{
			prime[j]=0;
		}
	}
}
int main()
{
	sievePrime();
	/*for(int i=2;i<=1000;i++)
	{
		if(prime[i])
		{
			cout<<i<<" ";	
		}
	}*/	
	//cout<<endl;
	int n;
	while(scanf("%d",&n)!=EOF&&n)
	{
		for(int i=3;i<maxm;i++)
		{
			if(i%2!=0)
			{
				if(prime[i])
				{
					if(prime[n-i])
					{
						printf("%d = %d + %d\n",n,i,n-i);
						//cout<<n<<" = "<<i<<" + "<<n-i<<endl;
						break;
					}
				}
			}
		}	
	}
	return 0;
}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics