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

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

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

相关推荐
方也_arkling6 小时前
【Java-Day08】static / final / 枚举
java·开发语言
橙淮6 小时前
Spring Bean作用域与生命周期全解析
java·spring
风吹夏回6 小时前
Python 全局异常处理:从“满屏 try-except”到优雅兜底
开发语言·python
Chengbei116 小时前
一站式源码安全检测工具、云安全 / APP / 小程序源码敏感信息递归多层目录扫描AK、JWT、手机号、身份证等敏感信息
java·开发语言·安全·web安全·网络安全·系统安全·安全架构
llz_1126 小时前
web-第一次课后作业
java·开发语言·idea
小熊Coding6 小时前
Python爬取当当网二手图书项目实战!
开发语言·爬虫·python·beautifulsoup·requests·二手图书
秋96 小时前
Java项目运行5天左右自动宕机:系统性定位与解决方案
java·开发语言·python
小江的记录本7 小时前
【JVM虚拟机】垃圾回收GC:垃圾收集器:CMS:核心原理、回收流程、优缺点、废弃原因(附《思维导图》+《面试高频考点清单》)
java·jvm·后端·python·spring·面试·maven
xiaoshuaishuai87 小时前
C# 内存管理与资源泄漏
开发语言·c#
DIY源码阁7 小时前
JavaSwing学生成绩管理系统 - MySQL版
java·数据库·mysql·eclipse