原创文章转载请注明出处
摘要:
数论,质数 , 回文数
一. 题目翻译
1. 描述:
因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数。
写一个程序来找出范围[a,b](5 <= a < b <= 100,000,000)( 一亿)间的所有回文质数;
2. 格式:
INPUT FORMAT:
(file pprime.in)
第 1 行: 二个整数 a 和 b .
OUTPUT FORMAT:
(file pprime.out)
输出一个回文质数的列表,一行一个。
SAMPLE INPUT:
5 500
SAMPLE OUTPUT:
5
7
11
101
131
151
181
191
313
353
373
383
1. 题意理解(将问题分析清楚,大致用什么思路):
参考了nocow上面的说明。
我们的做法是从小到大生成一个回文数,然后判断是否为质数。生成回文数的方法是枚举产生从最高位到中间位的数,然后复制到低位即可(例如4位数,我们产生一个两位数作为第4位和第3位,然后复制到第2位和第一位)。
这里有一个非常重要的优化就是所有的偶数回文数只有11是质数。也就是说我们只需要枚举产生奇数位的回文数即可,这样减少了一半的时间复杂度。
2.
具体实现(具体实现过程中出现的问题):
我们根据输入的a来判断要产生的回文数是多少位的, 我们用jumpi==true表示需要跳过产生i位的回文数。例如:输入a=11111,那么jump1、jump3为true,表示我们不需要产生1位与3位的回文数,从5位的回文数开始产生,判断质数。
三. 代码
/*
ID:fightin1
LANG:JAVA
TASK:pprime
*/
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Scanner;
public class pprime {
public static void main(String[] args) {
try {
Scanner in = new Scanner(new BufferedReader(new FileReader(
"pprime.in")));
PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(
"pprime.out")));
int a = in.nextInt();
int b = in.nextInt();
print(a, b, pw);
pw.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static boolean isP(int num) {
int mid =(int)Math.sqrt(num);
for (int i=2;i<=mid;i++){
if (num%i == 0){
return false;
}
}
return true;
}
public static int print(int a, int b ,PrintWriter pw){
boolean jump1 = false ;
boolean jump3 = false ;
boolean jump5 = false ;
boolean jump7 = false ;
if (a > 11){
jump1 = true ;
}
if (a >=1000){
jump1 = true ;
jump3 = true ;
}
if (a >= 100000){
jump1 = true ;
jump3 = true ;
jump5 = true ;
}
if (a>=10000000){
jump1 = true ;
jump3 = true ;
jump5 = true ;
jump7 = true ;
}
if (!jump1){
for (int i = a;i<=9;i++){
if(i>b){
return 0;
} else {
if (isP(i)){
pw.println(i);
}
}
}
pw.println("11");
}
if (!jump3){
for (int i = 1;i<=9;i+=2){
for (int j=0;j<=9;j++){
int num = i*100 + j*10 + i;
if (num <a){
continue;
}
if(num>b){
return 0;
} else {
if (isP(num)){
pw.println(num);
}
}
}
}
}
if (!jump5){
for (int i = 1;i<=9;i+=2){
for (int j=0;j<=9;j++){
for (int k=0;k<=9;k++){
int num = i*10000 + j*1000 + k*100 + j*10 + i;
if (num <a){
continue;
}
if(num>b){
return 0;
} else {
if (isP(num)){
pw.println(num);
}
}
}
}
}
}
if (!jump7){
for (int i = 1;i<=9;i+=2){
for (int j=0;j<=9;j++){
for (int k=0;k<=9;k++){
for(int m=0;m<=9;m++){
int num = i*1000000 + j*100000 + k*10000 + m*1000 + k*100 + j*10 + i;
if (num <a){
continue;
}
if(num>b){
return 0;
} else {
if (isP(num)){
pw.println(num);
}
}
}
}
}
}
}
return 0;
}
}