因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数.
写一个程序来找出范围[a,b](5<=a<b<=100,000,000)间的所有回文质数;
因为 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数.写一个程序来找出范围[a,b](5<=a<b<=100,000,000)间的所有回文质数;
*Line 1: a,b
a与b之间(含)的所有回文质数
一行一个
5 500
5
7
11
101
131
151
181
191
313
353
373
383
先找回文数,再判断是不是质数。
代碼實現(codevs 38ms,洛谷 44ms):
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 int a,b,c,s; 5 int hw[300000]; 6 void find(int x){ 7 c=s=x;c/=10; 8 while(c){s*=10;s+=c%10;c/=10;}//构造奇数数位的回文。 9 if(s>b) return; 10 if(s>=a) hw[++hw[0]]=s;//满足条件的回文,录入。 11 c=s=x; 12 while(c){s*=10;s+=c%10;c/=10;}//构造偶数数位的回文。 13 if(s>b) return; 14 if(s>=a) hw[++hw[0]]=s;//满足条件的回文,录入。 15 for(int i=0;i<10;i++) find(10*x+i);//继续寻找。 16 } 17 int main(){ 18 scanf("%d%d",&a,&b); 19 for(int i=1;i<=9;i+=2){ 20 s=i; 21 find(i); 22 } 23 sort(hw+1,hw+hw[0]+1);//排序,因为要求顺序输出 24 for(int i=1;i<=hw[0];i++) 25 for(int j=2;j*j<=hw[i];){ 26 if(hw[i]%j==0) break; 27 j++; 28 if(j*j>hw[i]) printf("%d\n",hw[i]);//输出素数。 29 } 30 return 0; 31 }
应老师要求,稍微优化了一下(codevs 4ms,洛谷 25ms):
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 const int maxn=4010; 5 int a,b,c,s; 6 int hw[300000]; 7 int zs[maxn],zsm,d,l,re; 8 char ch[30]; 9 bool v[maxn+10]; 10 int read(){ 11 l=0,re=0; 12 while(ch[l]=getchar()) 13 if(ch[l]>='0'&&ch[l]<='9') break; 14 l++; 15 while(ch[l]=getchar()){ 16 if(ch[l]>='0'&&ch[l]<='9') l++; 17 else break; 18 } 19 for(int i=0;i<l;i++) re=re*10+ch[i]-'0'; 20 return re; 21 } 22 void write(int x){ 23 l=0; 24 while(x){ch[l++]=x%10+'0';x/=10;} 25 for(int i=l-1;i>=0;i--) putchar(ch[i]); 26 putchar('\n'); 27 } 28 void find(int x){ 29 c=s=x;c/=10; 30 while(c){s*=10;s+=c%10;c/=10;} 31 if(s>b) return; 32 if(s>=a&&(s%11||s==11)) hw[++hw[0]]=s; 33 for(int i=0;i<10;i++) find(10*x+i); 34 } 35 int main(){ 36 for(int i=2;i<=maxn;i++) 37 if(!v[i]){ 38 zs[zsm++]=i;d=i+i; 39 while(d<=maxn){v[d]=1;d+=i;} 40 } 41 a=read();b=read(); 42 for(int i=1;i<=9;i+=2){s=i;find(i);} 43 if(11>=a&&11<=b) hw[++hw[0]]=11; 44 sort(hw+1,hw+hw[0]+1); 45 for(int i=1;i<=hw[0];i++){ 46 d=0; 47 while(1){ 48 if(hw[i]%zs[d++]==0) break; 49 if(zs[d]*zs[d]>hw[i]||d>zsm){write(hw[i]);break;} 50 } 51 } 52 return 0; 53 }
codevs上跑4ms的不是这段代码,但这段代码理论上更优,可能是评测机不在状态吧。不敢继续攻击网站了。
题目描述
因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。
写一个程序来找出范围[a,b](5 <= a < b <= 100,000,000)( 一亿)间的所有回文质数;
输入输出格式
输入格式:
第 1 行: 二个整数 a 和 b .
输出格式:
输出一个回文质数的列表,一行一个。
输入输出样例
5 500
5 7 11 101 131 151 181 191 313 353 373 383
说明
Hint 1: Generate the palindromes and see if they are prime.
提示 1: 找出所有的回文数再判断它们是不是质数(素数).
Hint 2: Generate palindromes by combining digits properly. You might need more than one of the loops like below.
提示 2: 要产生正确的回文数,你可能需要几个像下面这样的循环。
题目翻译来自NOCOW。
USACO Training Section 1.5
产生长度为5的回文数:
for (d1 = 1; d1 <= 9; d1+=2) { // 只有奇数才会是素数 for (d2 = 0; d2 <= 9; d2++) { for (d3 = 0; d3 <= 9; d3++) { palindrome = 10000*d1 + 1000*d2 +100*d3 + 10*d2 + d1;//(处理回文数...) } } }
如果先判素数,再判断是不是回文数会超时。
因为,很明显,素数比回文数多得多。
代码实现(88):
1 #include<cstdio> 2 int a,b,c,d,l; 3 char ch[12]; 4 bool v[100000010]; 5 int main(){ 6 scanf("%d%d",&a,&b); 7 for(int i=2;i<=b;i++) 8 if(!v[i]){ 9 c=2*i;d=i;l=0; 10 if(i>=a){ 11 for(l=0;l<9;l++){ 12 ch[l]=d%10+'0';d/=10; 13 if(!d) break; 14 } 15 for(int i=0;i<=l;i++){ 16 if(ch[i]!=ch[l-i]) break; 17 if(i==l) printf("%s\n",ch); 18 } 19 } 20 while(c<=b){v[c]=1;c+=i;} 21 } 22 return 0; 23 }
应该先找到满足要求的回文数,而后判断其是否为素数。
代码实现(AC):
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 int a,b,c,s; 5 int hw[300000]; 6 void find(int x){//find到所有回文数,并存入hw数组。 7 c=s=x;c/=10; 8 while(c){s*=10;s+=c%10;c/=10;} 9 if(s>b) return; 10 if(s>=a) hw[++hw[0]]=s; 11 c=s=x; 12 while(c){s*=10;s+=c%10;c/=10;} 13 if(s>b) return; 14 if(s>=a) hw[++hw[0]]=s; 15 for(int i=0;i<10;i++) find(10*x+i); 16 } 17 int main(){ 18 scanf("%d%d",&a,&b); 19 for(int i=1;i<=9;i+=2){ 20 s=i; 21 find(i); 22 } 23 sort(hw+1,hw+hw[0]+1);//因为调整回文输入先后太麻烦,所有加了个快排,当然,由于上面的原因,时间上是允许的。 24 for(int i=1;i<=hw[0];i++) 25 for(int j=2;j*j<=hw[i];){ 26 if(hw[i]%j==0) break;j++; 27 if(j*j>hw[i]) printf("%d\n",hw[i]); 28 } 29 return 0; 30 }
有点恶心。
题目来源 CODE[VS],洛谷