POJ-2689 Prime Distance(筛素数的平移)
2017-11-26 12:55
429 查看
题目:POJ-2689 Prime Distance
题目大意:给定一个区间[l,r],让求区间当中相邻素数组中距离最小的一组素数以及距离最大的一组素数。
解题思路:分析一下数据发现,虽然区间的右端点的最大值可以达到2^32左右,但是,区间的跨度确实极小的,应用这个,可以通过筛两次素数,第一次正常筛出2^16以内的素数,第二次对筛法进行区间平移,从区间的左端点开始筛除即可。这里注意左端点的处理:
1.l=(x-1)/prime[i]+1,因为x本身可能是prime[i]的倍数,若不减去1直接在最后加1可能就忽略了区间的左端点,排除这种情况先进行x-1操作。
2.(l<2)l=2,小于2第一个数就刚好是prime[i],这时从下一个数开始筛。
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 100010
using namespace std;
bool visit[maxn];
int prime[maxn];
int total;
bool q[1000010];
void getprime(){
int i,j;
total=0;
memset (visit,0,sizeof(visit));
for (i=2;i<maxn;i++){
if (visit[i]==0){
prime[++total]=i;
for (j=2*i;j<maxn;j+=i){
visit[j]=1;
}
}
}
}
int main(){
int i,j,x,y;
getprime();
while (scanf("%d%d",&x,&y)!=EOF){
memset (q,0,sizeof(q));
for (i=1;i<=total&&prime[i]<=y;i++){
int l=(x-1)/prime[i]+1;
if (l<2)l=2;
int r=y/prime[i];
for (j=l;j<=r;j++){
q[j*prime[i]-x]=1;
}
}
int minn=1000100,maxx=0,pre=-1,y1,y2;
for (i=0;i<=y-x;i++){
if (q[i]==0){
if (pre!=-1){
int dis=i-pre;
if (minn>dis){
minn=dis;
y1=i;
}
if (maxx<dis){
maxx=dis;
y2=i;
}
}
if (i+x!=1)pre=i;
}
}
if (minn==1000100&&maxx==0){
printf("There are no adjacent primes.\n");
}
else {
int x1,x2;
y1+=x;
x1=y1-minn;
y2+=x;
x2=y2-maxx;
printf("%d,%d are closest, %d,%d are most distant.\n",x1,y1,x2,y2);
}
}
}
题目大意:给定一个区间[l,r],让求区间当中相邻素数组中距离最小的一组素数以及距离最大的一组素数。
解题思路:分析一下数据发现,虽然区间的右端点的最大值可以达到2^32左右,但是,区间的跨度确实极小的,应用这个,可以通过筛两次素数,第一次正常筛出2^16以内的素数,第二次对筛法进行区间平移,从区间的左端点开始筛除即可。这里注意左端点的处理:
1.l=(x-1)/prime[i]+1,因为x本身可能是prime[i]的倍数,若不减去1直接在最后加1可能就忽略了区间的左端点,排除这种情况先进行x-1操作。
2.(l<2)l=2,小于2第一个数就刚好是prime[i],这时从下一个数开始筛。
AC代码:
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 100010
using namespace std;
bool visit[maxn];
int prime[maxn];
int total;
bool q[1000010];
void getprime(){
int i,j;
total=0;
memset (visit,0,sizeof(visit));
for (i=2;i<maxn;i++){
if (visit[i]==0){
prime[++total]=i;
for (j=2*i;j<maxn;j+=i){
visit[j]=1;
}
}
}
}
int main(){
int i,j,x,y;
getprime();
while (scanf("%d%d",&x,&y)!=EOF){
memset (q,0,sizeof(q));
for (i=1;i<=total&&prime[i]<=y;i++){
int l=(x-1)/prime[i]+1;
if (l<2)l=2;
int r=y/prime[i];
for (j=l;j<=r;j++){
q[j*prime[i]-x]=1;
}
}
int minn=1000100,maxx=0,pre=-1,y1,y2;
for (i=0;i<=y-x;i++){
if (q[i]==0){
if (pre!=-1){
int dis=i-pre;
if (minn>dis){
minn=dis;
y1=i;
}
if (maxx<dis){
maxx=dis;
y2=i;
}
}
if (i+x!=1)pre=i;
}
}
if (minn==1000100&&maxx==0){
printf("There are no adjacent primes.\n");
}
else {
int x1,x2;
y1+=x;
x1=y1-minn;
y2+=x;
x2=y2-maxx;
printf("%d,%d are closest, %d,%d are most distant.\n",x1,y1,x2,y2);
}
}
}
相关文章推荐
- POJ-2689 Prime Distance (两重筛素数,区间平移)
- 数论 - 素数的运用 --- poj 2689 : Prime Distance
- POJ2689:Prime Distance(大区间素数)
- poj 2689 Prime Distance (double筛筛出大素数)
- Poj 2689 Prime Distance【素数区间筛】
- Prime Distance poj 2689 区间内的素数打表模板
- POJ 2689 Prime Distance [筛法选取素数]【数论】
- Poj 2689 Prime Distance ----大区间素数筛选
- 【POJ - 2689】 Prime Distance 【素数区间筛】
- POJ 2689 Prime Distance (二次?筛素数)
- poj 2689 Prime Distance 筛法/二次筛法/区间素数
- POJ 2689 - Prime Distance 任意区间内筛素数
- POJ 2689 Prime Distance(大区间素数筛选)
- poj 2689 Prime Distance(大区间筛素数)
- POJ 2689 Prime Distance(素数区间筛法--经典题)
- poj 2689 Prime Distance 筛法+区间筛素数
- POJ 2689 Prime Distance(筛选两次素数)
- POJ - 2689 - Prime Distance - (区间大数筛素数)
- poj 2689 Prime Distance (素数二次筛法)
- poj 2689 Prime Distance 筛素数加强版