洛谷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;
    }
}

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

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

相关推荐
水云桐程序员2 小时前
C++可以写手机应用吗
开发语言·c++·智能手机
测试员周周3 小时前
【AI测试智能体】为什么传统测试方法对智能体失效?
开发语言·人工智能·python·功能测试·测试工具·单元测试·测试用例
RSTJ_16253 小时前
PYTHON+AI LLM DAY THREETY-NINE
开发语言·人工智能·python
想学习java初学者4 小时前
SpringBoot整合Vertx-Mqtt多租户(优化版)
java·spring boot·后端
AC赳赳老秦4 小时前
政企内网落地:OpenClaw 离线环境深度适配方案,无外网场景下本地化模型对接与全功能使用
java·大数据·运维·python·自动化·deepseek·openclaw
赏金术士4 小时前
Kotlin 从入门到进阶 之函数模块(核心基础)(二)
android·开发语言·kotlin
weixin_449173654 小时前
在 Java 中,‌线程安全的 List‌ 主要有以下几种实现方式,它们的效率取决于具体的使用场景(尤其是读写比例):
java·线程安全的list
砚底藏山河4 小时前
股票数据API接口:如何获取股票历历史分时KDJ数据
java·python·maven
MegaDataFlowers6 小时前
运行若依项目
java
加号36 小时前
【Qt】 应用程序发布:依赖库拷贝与部署指南
开发语言·qt