[USACO 1.5.2] Prime Palindromes

来源:互联网 发布:asp.net 获取域名 编辑:程序博客网 时间:2024/05/19 03:20

[题目描述]

Prime Palindromes

回文质数

因为151即是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 号是回文质数。
写一个程序来找出范围[a,b](5 <= a < b <= 100,000,000)间的所有回文质数;

PROGRAM NAME: pprime

INPUT FORMAT
第 1 行: 二个整数 a 和 b .

SAMPLE INPUT (file pprime.in) 
5 500

OUTPUT FORMAT
输出一个回文质数的列表,一行一个。

SAMPLE OUTPUT (file pprime.out)
5
7
11
101
131
151
181
191
313
353
373
383


[解题思路]

想了个很奇葩的方法竟然过了! = =、

本来是想打表的,一千万的表加上检验是否回文,估计会TLE。

所以我就想是否可以构造出回文串,再去判断它是否合法(即在[a,b]范围内,并且是素数)。100,000,000,最多9位数,所以我枚举1~99999这些数字构造两种回文串(奇数长度与偶数长度),再转换为数字,用Miller-Rabin可以快速判定大素数,以此检验,最后排序输出。效率较高,并且稳定,所有测试点都基本是0.17过的。


[Code]

{ID: zane2951PROG: pprimeLANG: PASCAL}program pprime;const   p:array[1..7] of longint=(2,3,5,7,11,13,17);var   i,code:longint;   ce,a,b,top:int64;   s:string;   q:array[0..1111111] of longint;//----------make1-----------function make1(x:longint):string;var   ce:longint;begin   str(x,make1);   while x>0 do      begin         ce:=x mod 10;         make1:=make1+chr(ce+ord('0'));         x:=x div 10;      end;end;//----------make2-----------function make2(x:longint):string;var   ce:longint;begin   str(x,make2);   x:=x div 10;   while x>0 do      begin         ce:=x mod 10;         make2:=make2+chr(ce+ord('0'));         x:=x div 10;      end;end;//-----------mul-----------function mul(a,b,mo:int64):longint;begin   mul:=1;   while b>0 do      begin         if b and 1>0 then mul:=(mul*(a mod mo)) mod mo;         a:=((a mod mo)*(a mod mo)) mod mo;         b:=b>>1;      end;end;//----------check----------function check(x:int64):boolean;var   i:longint;   ce:int64;begin   if (x=5) or (x=7) then exit(true);   for i:=1 to 7 do      if p[i]<>x then         begin            ce:=mul(p[i],x-1,x);            if ce<>1 then exit(false);         end;   exit(true);end;//-----------qs------------procedure qs(s,t:longint);var   i,j,ce,tmp:longint;begin   i:=s; j:=t; ce:=q[(i+j)>>1];   repeat      while q[i]<ce do inc(i);      while q[j]>ce do dec(j);      if i<=j then         begin            tmp:=q[i]; q[i]:=q[j]; q[j]:=tmp;            inc(i); dec(j);         end;   until i>j;   if i<t then qs(i,t); if s<j then qs(s,j);end;//----------main-----------begin   assign(input,'pprime.in'); reset(input);   assign(output,'pprime.out'); rewrite(output);   readln(a,b); top:=0;   for i:=1 to 99999 do      begin         s:=make1(i);         val(s,ce,code);         if (ce>=a) and (ce<=b) then            if check(ce) then begin inc(top); q[top]:=ce; end;         s:=make2(i);         val(s,ce,code);         if (ce>=a) and (ce<=b) then            if check(ce) then begin inc(top); q[top]:=ce; end;      end;   qs(1,top);   for i:=1 to top do writeln(q[i]);   close(input); close(output);end.