您的位置:首页 > 其它

poj-2689素数筛选

2015-08-05 11:02 363 查看
这道题目我就不贴题目了,就是素数筛选题。

这道题目差点让我崩溃,自己太菜的原因,提交了很多次,总是runtime error ,后来才知道,素数筛选的范围这能是2^16,然而这道题给的范围超出了int的上界,所以,必须要用另外一种方法来筛选,看了人家的博客,感觉方法超好。这道题有个突破点,就是区间在100000之内,所以,我们找到它们的合子的位置即可。

先筛出50000以内的素数,然后再在给定的区间内以刚刚的素数为基底,筛出区间内的素数。筛的过程中算出区间左值是最小素数的几倍,然后然后不是整数倍,就往前加1(否则算出的数会不在这个区间里,没意义),然后这个整数倍乘以素数已经大于右边了,那就可以直接退出了。

这里写代码
#include <iostream>
#include <cmath>
#include<cstring>
using namespace std;
const int N=50000;
const int Max=999999999;//定义为无穷大
int r[1000000],a[N+100],b[N+100],z;
int main()
{
int l,u,i,j;
for (i=2;i<=N;i++)//素数筛选
if (!a[i])
{
b[++z]=i;
for (j=i+i;j<=N;j+=i)
a[j]=1;
}
while (cin>>l>>u)
{
memset(r,0,sizeof(r));
int dis,max=-1,min=Max,maxc,minc;
for (i=1;i<=z;i++)//关键算法在于这里
{
int s,t;
s=(l-1)/b[i]+1;
t=u/b[i];
for (j=s;j<=t;j++)
if (j>1)
r[j*b[i]-l]=1;
}
int k=-1;
for (i=0;i<=u-l;i++)//这里就是遍历找相邻最近和最远的,其实这里理解容易些
if (!r[i])
{
if (k!=-1)
{
dis=i-k;
if (dis>max)
{
max=dis;
maxc=i+l;
}
if (dis<min)
{
min=dis;
minc=i+l;
}
}
if (i+l!=1) k=i;
}
if (max<0)
{
cout<<"There are no adjacent primes."<<endl;
}
else
{
cout<<minc-min<<','<<minc<<" are closest, ";
cout<<maxc-max<<','<<maxc<<" are most distant."<<endl;
}
}
return 0;
}


希望各位大牛们多多指教!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: