I and OI
Past...

题意:求[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.
posted on 2011-08-13 13:31  exponent  阅读(782)  评论(0编辑  收藏  举报