洛谷P1217回文质数

java 复制代码
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
    	
        Scanner scan = new Scanner(System.in);
        
        int a = scan.nextInt();
        
        int b = scan.nextInt();
        
        scan.close();

        // 优化5:最大的回文质数是9989899
        if (b > 9989899) {
            b = 9989899;
        }

        // 优化1:如果a是偶数,从下一个奇数开始
        if (a % 2 == 0) {
            a++;
        }

        for (int i = a; i <= b; i += 2) { // 只检查奇数

            // 优化2:排除偶数位数的数字(除了11)
            if (i > 11 && String.valueOf(i).length() % 2 == 0) {
                continue;
            }

            // 优化3:先判断回文
            if (isPalindrome(i)) {
                // 后判断质数
                if (isPrime(i)) {
                    System.out.println(i);
                }
            }
        }
    }

    // 优化4:高效的质数判断
    public static boolean isPrime(int num) {
        if (num < 2) return false;
        if (num == 2) return true;
        if (num % 2 == 0) return false; // 排除偶数

        // 只检查到平方根,并且只检查奇数因子
        for (int i = 3; i * i <= num; i += 2) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

    // 高效的整数回文判断,避免字符串转换
    public static boolean isPalindrome(int num) {
        if (num < 0) return false;
        if (num < 10) return true;

        int reversed = 0;
        int original = num;
        while (num > 0) {
            reversed = reversed * 10 + num % 10;
            num /= 10;
        }
        return original == reversed;
    }
}

题目大意及思路

这道题目是要我们找出并输出为于你输入的两个数a和b之间的所有既是质数又是回文数的数,但是5<=a<=b<=1亿,这个题目本身难度不高,只是如果不筛选和优化判断方法则很容易出现超时现象。要想不超时,那么首先我们就得想办法把a到b的区间内的不可能是回文质数的数给筛选掉。那么该如何筛选呢首先我们知道所有的偶数必然不可能是质数,所以我们可以把偶数给筛选掉,还有我们所有位数长度是偶数的回文数必然可以被11整除,所以可以把所有的位数长度为偶数的数字筛选掉。

有人可能疑惑既然是所有位数长度为偶数的回文数不可能是质数那为什么要把所有的位数长度为偶数的数删掉,这是因为你可以把所有位数长度是偶数的数分为两类,一类是回文数一类是非回文数,而我们要找的是回文质数,既是回文数又是质数,第一类因为说过不可能是质数,而第二类甚至都不是回文数,所以所有的位数长度为偶数的数都要筛选掉。

java 复制代码
 // 优化5:最大的回文质数是9989899
        if (b > 9989899) {
            b = 9989899;
        }

        // 优化1:如果a是偶数,从下一个奇数开始
        if (a % 2 == 0) {
            a++;
        }

先来看两个优化既然偶数不可能是质数那么区间下限a如果是偶数可以把它赋值为比它刚好大一的奇数,并且这个操作也方便了后面遍历时可以遍历到区间内的所有质数,还有,小于1亿的数里,最大的回文质数是9989899,所以大于9989899的数不用判断,当b大于9989899的时候直接赋值为9989899。

java 复制代码
for (int i = a; i <= b; i += 2) { // 只检查奇数

            // 优化2:排除偶数位数的数字(除了11)
            if (i > 11 && String.valueOf(i).length() % 2 == 0) {
                continue;
            }

            // 优化3:先判断回文
            if (isPalindrome(i)) {
                // 后判断质数
                if (isPrime(i)) {
                    System.out.println(i);
                }
            }
        }
    }

这个首先注意这个循环,i += 2i是加2加2的递增的,前面又确保了区间下界是奇数所以确保了所有遍历到的数都是奇数。

同时

java 复制代码
if (i > 11 && String.valueOf(i).length() % 2 == 0) {
                continue;
            }

又把所有的位数长度为偶数的数给筛选掉了。到此所有需要筛选的数已经全部筛掉。

接下来看判断部分的代码

java 复制代码
// 优化4:高效的质数判断
    public static boolean isPrime(int num) {
        if (num < 2) return false;
        if (num == 2) return true;
        if (num % 2 == 0) return false; // 排除偶数

        // 只检查到平方根,并且只检查奇数因子
        for (int i = 3; i * i <= num; i += 2) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

    // 高效的整数回文判断,避免字符串转换
    public static boolean isPalindrome(int num) {
        if (num < 0) return false;
        if (num < 10) return true;

        int reversed = 0;
        int original = num;
        while (num > 0) {
            reversed = reversed * 10 + num % 10;
            num /= 10;
        }
        return original == reversed;
    }
}

回文数反转的方法很容易看懂不多解释

这里只说说判断质数的方法,首先要记住一个数如果不是质数,那么这个数一定有一个不大于它开方后的因子。所以在判断质数的方法中只需要让这个数除到这个数的开方即可。

相关推荐
非优秀程序员3 小时前
第04章 邮箱大战,163 与 QQ 的暗战|《互联网产品恩仇录》
java·vue.js·架构
知已难寻3 小时前
Docker 入门:容器技术与 Docker 基础
java·运维·服务器·docker·云原生·容器
沐晓时光3 小时前
C语言入门,内存函数知识讲解
c语言·开发语言
文丑颜不良啊5 小时前
LeetCode2481~2500题目解析
java·leetcode
Flynn Liang6 小时前
同一需求三套写法:用 Spring AI、LangChain4j、AgentScope Java 各实现一个带工具调用的 RAG 助手(实战对比)
java·人工智能·大模型·架构设计·spring ai·langchain4j·agentscope
聪明的笨猪猪7 小时前
实际工程问题:AI 生成 Spring Cache(@Cacheable / @CachePut / @CacheEvict)缓存注解踩坑
java·经验分享·面试·ai编程
愿有所息7 小时前
记一次 ARM64 + JDK8 上 fastjson2 的诡异数据错乱
java
秋饼7 小时前
MCP 2026-07-28 无状态协议大改版:Spring AI 2.1 多轮往返请求与网关路由落地
java·ai·技术分享·后端开发
SL_staff9 小时前
JVS-BI 实战:业务人员如何用零代码 ELT + 可视化配置构建实时经营分析闭环
java·spring·全栈
SL_staff9 小时前
企业AI落地难?JVS-AI渐进式实践:安全可控、小切口验证、标准化沉淀与规模化复制
java·开源·aigc