题意:求[L,U]区间内相差最大和最小的两对素数.(1<=L<U<=2,147,483,647,U-L<=1000000)
分析:先筛出sqrt(maxlongint)范围内的素数,再用这些素数去筛L~U范围内的素数.
code:
const MAXNUM=50000; MAXN=1000001; MAXM=200000; oo=1000000000; var Prime:array[0..MAXNUM] of longint; P:array[0..MAXNUM] of boolean; d:array[0..MAXN] of boolean; px:array[0..MAXM] of longint; size,l,u,o,pcnt:longint; max,min,maxa,mina,maxb,minb:longint; procedure GetPrime; var i,j,tmp:longint; begin size:=0; fillchar(P,sizeof(P),0); for i:=2 to MAXNUM do begin if not P[i] then begin inc(size); prime[size]:=i; end; j:=1; while (j<=size)and(prime[j]*i<MAXNUM) do begin P[i*prime[j]]:=true; if i mod prime[j]=0 then break; inc(j); end; end; end; procedure Makeprime; var i:longint; j:int64; begin fillchar(d,sizeof(d),0); for i:=1 to size do begin if prime[i]>u then break; j:=l; if j mod prime[i]=0 then begin if j=prime[i] then inc(j,prime[i]); while j<=u do begin d[j-l]:=true; inc(j,prime[i]); end end else begin if j<prime[i] then j:=prime[i]*2 else j:=(j div prime[i]+1)*prime[i]; while j<=u do begin d[j-l]:=true; inc(j,prime[i]); end; end; end; end; begin GetPrime; while not eof do begin readln(L,U); Makeprime; pcnt:=0; for o:=0 to u-l do if not d[o] then begin if o+l=1 then continue; inc(pcnt); px[pcnt]:=o+l; end; if pcnt<=1 then begin writeln('There are no adjacent primes.'); continue; end; max:=-oo; min:=oo; for o:=2 to pcnt do begin if px[o]-px[o-1]>max then begin maxa:=px[o-1]; maxb:=px[o]; max:=px[o]-px[o-1]; end; if px[o]-px[o-1]<min then begin mina:=px[o-1]; minb:=px[o]; min:=px[o]-px[o-1]; end; end; writeln(mina,',',minb,' are closest, ',maxa,',',maxb,' are most distant.'); end; end.