POJ 2689 Prime Distance (素数+两次筛选)
题目地址:http://poj.org/problem?id=2689
题意:给你一个不超过1000000的区间L-R,要你求出区间内相邻素数差的最大最小值,输出相邻素数。
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <cmath> #include <vector> #include <list> #include <deque> #include <queue> #include <iterator> #include <stack> #include <map> #include <set> #include <algorithm> #include <cctype> using namespace std; typedef long long LL; const int N=1<<16; const int M=1000005; const int mod=1000007; const int INF=0x3f3f3f3f; const double PI=acos(-1.0); int pri[N],k; void xh_phi() { int i,j; memset(pri,0,sizeof(pri)); k=0; for(i=2;i<=N;i++) { if(!pri[i]) { pri[++k]=i; for(j=i;j<=N;j+=i) pri[j]=1; } } } int prime[M],t; bool nopri[M]; void getprime(int L,int R) { int i,j; memset(nopri,false,sizeof(nopri)); if(L<2) L=2; for(i=1;i<=k&&(LL)pri[i]*pri[i]<=R;i++) { int s=L/pri[i]+(L%pri[i]>0); if(s==1) s=2; for(j=s;(LL)j*pri[i]<=R;j++) if((LL)j*pri[i]>=L) nopri[j*pri[i]-L]=true; } prime[0]=0; t=0; for(i=0;i<=R-L;i++) if(!nopri[i]) { prime[++t]=i+L; } } int main() { int n,m,i,j; xh_phi(); while(~scanf("%d%d",&n,&m)) { getprime(n,m); int Mi=INF,Ma=0; int x1,x2,y1,y2,f=0; if(t<2) { printf("There are no adjacent primes.\n"); continue; } for(i=1;i<t;i++) { int p=prime[i+1]-prime[i]; if(p>Ma) { Ma=p;x2=prime[i];y2=prime[i+1]; } if(p<Mi) { Mi=p;x1=prime[i];y1=prime[i+1]; } } printf("%d,%d are closest, %d,%d are most distant.\n",x1,y1,x2,y2); } return 0; }