筛选素数法
搞ACM的都知道,素数是数论中必不可少的知识,也是必须要掌握的,关于素数的筛选有好几种方法,下面一一道来,写的不好还请提出。
第一种是最常规的做法
int main()
{
int i,j,m,n,g,t;
cin>>n;
for(i=2;i<=n;i++)
{
for(j=2;j<i;j++)
{
if(i%j==0)
break;
}
if(j==i)
cout<<i<<endl;
}
}
简单的两个循环很好理解,这种方法优点是易理解,写得出。缺点是对于非常大的数,比如100000000,测试过了十几分钟最起码的。。。。
第二种升级一下
int main()
{
int i,j,m,n,g,t;
cin>>n;
for(i=2;i<=n;i++)
{
for(j=2;j<=sqrt(i);j++)
{
if(i%j==0)
break;
}
if(j > sqrt(i))
cout<<i<<endl;
}
}
这种方法肯定是比第一种快的,至于快多少大家可以比较一下,注意到里面的for循环是到sqrt(i)就结束的,并不是到i,大家都知道,一个数的合数的所有因子不会大于这个合数的根号。
第三种就是素数筛选法
int main()
{
int i,j,m,n,g,t;
int prime[100001]={0};
cin>>n;
for(i=2;i<=n;i+=2)
{
prime[i] = 0;
prime[i+1] = 1;
}
for(i=3;i<=sqrt(n);i+=2)
{
if(prime[i])
{
for(j=i+i;j<=n;j+=i)
prime[j] = 0;
}
}
for(i=2;i<=n;i++)
{
if(prime[i])
cout<<i<<endl;
}
}
思路是这样的,比如输入100以内的素数,先把所有的偶数的数组值标为0,奇数标为1(因为偶数不是素数。。),再从i=3开始循环,每次加一个倍数,即6,9,12,15,,,全部标为0,因为这些数都不是素数,再接着i=5开始,10,15,20,,,都标记为0,直到sqrt(n)结束循环,这里为什么要到sqrt(n)结束而不是n呢?因为在sqrt(n)之后的数字实际上都被前面的数遍历过并且标记过的。所以最后只需要把数组的值标记为1的输出来就是素数了。