标签:des style blog http io os ar for div
Waterloo local 1998.10.17
题目大意:给你一个区间【L,U】,求出从L到U之间素数序列中,连续两个素数差值最大
的最小的两对素数对,但其中(1<=L< U<=2,147,483,647),但区间【L,U】距离不超
过1000000
思路:因为L,U的值太大了,普通素性判断和素数筛法都不可行,所以可以考虑先筛选
一次,筛出50000以内的素数,然后用50000以内的素数再次筛选出区间【L,U】的素
数。第一次素数筛法比较简单,主要是第二次筛法,分别判断【L,U】中每个数是50000
以内的素数的多少倍,若为1倍,则从2倍开始筛选。若不为1倍,则考虑是否是整数倍,
若为整数倍,则从整数倍开始筛,否则从下1倍开始筛选
比如【L,U】为【50000,60000】,则50000为2的250000倍,应从2的25000倍筛选,
也就是50000,50002,50004,50006……筛去。
若【L,U】为【50001,60000】,则50001不为2的整数倍,应从2的250001倍筛选,也
就是50002,50004,50006……筛去。
参考博文:http://blog.csdn.net/returnzero__/article/details/7835655
#include<stdio.h>
#include<string.h>
bool Prime[50010];
int Primer[1000010];
bool Prime1[1000010];
int IsPrime()//第一次筛50000内的素数
{
int num = 0;
for(int i = 2; i <= 50000; i++)
Prime[i] = true;
for(int i = 2; i <= 50000; i++)
{
if(Prime[i])
{
Primer[num++] = i;
for(int j = i+i; j <= 50000; j+=i)
{
Prime[j] = false;
}
}
}
return num;
//num为50000范围内的素数个数
}
int solve(__int64 a,__int64 b)
/*
在第一次筛素数的基础上,利用50000以内的素数,筛去范围【a,b】之间的素数倍数,
剩下则为素数
*/
{
int num = IsPrime();
memset(Prime1,true,sizeof(Prime1));//Prime1数组用来存放范围【a,b】的素性判断
if(a == 1)//这里注意1不是素数
Prime1[0] = 0; //这里表示0+1不为素数
for(__int64 i = 0; i < num && Primer[i] * Primer[i] <= b; i++)
{
__int64 begin = a/Primer[i] + (a%Primer[i] != 0);
//上边的a/Primer算出应a为素数Primer[i]的多少倍
//(a%Primer[i]!=0)表示应从Primer[i]的a/Primer[i]倍开始筛,还是a/Primer[i]+1倍筛
if(begin == 1)//若得出结果为所被筛素数的1倍,则从该素数的2倍开始筛
begin++;
for(begin = begin*Primer[i]; begin <= b; begin += Primer[i])
Prime1[begin - a] = false;
}
//这里重新利用Primer数组,用来存放区间【a,b】间的素数,num为素数个数
memset(Primer,0,sizeof(Primer));
num = 0;
for(__int64 i = a; i <= b; i++)
{
if(Prime1[i-a]==1)
{
Primer[num++] = i-a;
}
}
return num;
}
int main()
{
__int64 a,b;
__int64 posa1,posb1,posa2,posb2;
while(~scanf("%I64d%I64d",&a,&b))
{
__int64 Max = -2147483647,Min = 2147483647;
int num = solve(a,b);
// for(__int64 i = 0; i < num; i++)
// printf("%I64d ",Primer[i]+a);
if(num <= 1)
{
printf("There are no adjacent primes.\n");
continue;
}
for(int i = 0; i < num-1; i++)//这里i+1范围为1到num-1,则i范围为0到num-2,之前一直错在这里
{
if(Primer[i+1]-Primer[i] < Min)
{
Min = Primer[i+1] - Primer[i];
posa1 = Primer[i];
posb1 = Primer[i+1];
}
if(Primer[i+1]-Primer[i] > Max)
{
Max = Primer[i+1] - Primer[i];
posa2 = Primer[i];
posb2 = Primer[i+1];
}
}
printf("%I64d,%I64d are closest, %I64d,%I64d are most distant.\n",posa1+a,posb1+a,posa2+a,posb2+a);
}
return 0;
}
POJ2689_Prime Distance【素数】【两次筛法】
标签:des style blog http io os ar for div
原文地址:http://blog.csdn.net/lianai911/article/details/39530015