题目描述
因为 151 151 151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 151 151 是回文质数。
写一个程序来找出范围 [ a , b ] ( 5 ≤ a < b ≤ 100 , 000 , 000 ) [a,b] (5 \le a < b \le 100,000,000) [a,b](5≤a<b≤100,000,000)(一亿)间的所有回文质数。
输入格式
第一行输入两个正整数 a a a 和 b b b。
输出格式
输出一个回文质数的列表,一行一个。
输入输出样例
输入
5 500
输出
5
7
11
101
131
151
181
191
313
353
373
383
方式
代码
python
class Solution:
@staticmethod
def oi_input():
"""从标准输入读取数据"""
left, right = map(int, input().split())
return left, right
@staticmethod
def oi_test():
"""提供测试数据"""
return 5, 500
@staticmethod
def solution(left, right):
def is_prime(n):
'''试除法,优化版'''
if n < 2:
return False
if n in (2, 3):
return True
if n % 2 == 0 or n % 3 == 0:
return False
i, w = 5, 2
while i * i <= n: # i 为除数 所以要不大于n的平方根
if n % i == 0:
return False
i += w
w = 6 - w
return True
def generate_palindromes():
'''回文数生成'''
yield 5
yield 7
yield 11
for length in [3, 5, 7]:
k = (length + 1) // 2
start, end = 10 ** (k - 1), 10 ** k # 左 与 右
for num in range(start, end):
s = str(num)
if s[0] not in {'1', '3', '7', '9'}: # 判断最后一位
continue
prefix, suffix = s, s[:-1][::-1] # 前半部分 与 去除了中间的后半部分
pal = int(prefix + suffix)
yield pal
prime_nums = []
for pal in generate_palindromes():
if left <= pal <= right and is_prime(pal):
prime_nums.append(pal)
for p in prime_nums:
print(p)
oi_input = Solution.oi_input
oi_test = Solution.oi_test
solution = Solution.solution
if __name__ == '__main__':
left, right = oi_test()
# left, right = oi_input()
solution(left, right)
流程图
回文数生成器 是 否 是 否 是 否 否 是 生成5,7,11 生成回文数序列 循环处理长度3/5/7 计算半长k=(length+1)//2 确定前缀范围[start=10^(k-1), end=10^k) 遍历前缀数字生成回文 前缀首位是否在1,3,7,9中? 构造回文数:前缀+逆序后缀 开始 输入区间left, right 初始化prime_nums列表 检查回文数是否在区间内 left ≤ pal ≤ right? 执行质数检查 跳过该回文数 是质数? 添加到prime_nums列表 循环结束? 输出所有prime_nums元素 结束