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

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

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

相关推荐
言乐630 分钟前
Python自动去除水印
开发语言·python·django·virtualenv·pygame
大圣编蚕32 分钟前
C语言入门:基本语法汇总
c语言·开发语言
czq_268671948734 分钟前
Python打卡第31天
开发语言·python
invicinble34 分钟前
python 编程语言 认识维度
开发语言·数据库·python
AC赳赳老秦36 分钟前
数据采集全链路审计留痕:用 OpenClaw 实现合规审计与追溯
开发语言·汇编·python·php·swift·deepseek·openclaw
czhc114007566340 分钟前
退出防呆:用“总闸“收口所有退出入口,以及三个并发语法坑
开发语言·c#
三8441 小时前
Fastjson 漏洞 · 02 · autoType 机制与 checkAutoType
java·fastjson
悠仁さん1 小时前
【C++】vector 类
开发语言·c++
_upupup1 小时前
智能指针的原理及简单模拟实现(C++)
开发语言·c++