一、题目
二、代码
def isPrime(num):
for i in range(3, int(num ** 0.5) + 1, 2):
if num % i == 0:
return False
return True
def palindrome(num):
return str(num) == str(num)[::-1]
def selfPrime(num):
count = 0
prime = 2
while True:
if len(str(prime)) == 4:
prime += 9000
if len(str(prime)) == 6:
prime += 900000
if isPrime(prime) and palindrome(prime):
count += 1
print(prime, end=" ")
if prime == 2:
prime += 1
continue
if count == num:
break
if len(str(prime)) > 5:
prime += 10
continue
prime += 2
if __name__ == '__main__':
selfPrime(eval(input()))
三、代码改进过程
1.初始版本
在最开始的时候,我的代码是这样的
def isPrime(num):
for i in range(2, int(num / 2) + 1):
if num % i == 0:
return False
return True
def palindrome(num):
return str(num) == str(num)[::-1]
def selfPrime(num):
count = 0
prime = 2
while True:
if isPrime(prime) and palindrome(prime):
count += 1
print(prime, end=" ")
if count == num:
break
prime += 1
selfPrime(eval(input()))
我先来解说一下这个代码
# 这个是一个判断是否为质数的函数 def isPrime(num): # 循环传进来的数字从2开始,然后把这个数除2减少循环次数,这是我最初的想法 for i in range(2, int(num / 2) + 1): # 如果在循环中被除尽了就说明他不是质数,反之就是质数 if num % i == 0: return False return True # 判断是否是回文的函数 def palindrome(num): # 直接返回,相等就是true,不相等就是false return str(num) == str(num)[::-1] # 这个就是主函数,判断是否为回文质数 def selfPrime(num): # count是用来控制次数 count = 0 # prime就是自己需要判断的数字 prime = 2 while True: # 只要符合是质数,回文也相等的数 if isPrime(prime) and palindrome(prime): # count+1,并输出这个数 count += 1 print(prime, end=" ") # 当count数和输入的数字相等时就代表可以结束循环了 if count == num: break # 需要让prime一次次增加,判断这个数是不是回文质数 prime += 1 # 最后这个就是运行了 selfPrime(eval(input()))
只不过在test5的地方超时了
这就说明我的代码还不够效率
2.改进版本
第一次改进
import math
def isPrime(num):
k = int(math.sqrt(num))
for i in range(3, k + 1, 2):
if num % i == 0:
return False
return True
def palindrome(num):
return str(num) == str(num)[::-1]
def selfPrime(num):
count = 0
prime = 2
while True:
if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
prime += 1
continue
elif isPrime(prime) and palindrome(prime):
count += 1
print(prime,end=" ")
if count == num:
break
prime += 1
selfPrime(eval(input()))
第一次改进在于判断质数的改进和判断回文质数的改进
import math def isPrime(num): # 将传入的数开根号并转为int类型 k = int(math.sqrt(num)) # 从3开始循环,循环到k+1并且步长为2 for i in range(3, k + 1, 2): if num % i == 0: return False return True def palindrome(num): return str(num) == str(num)[::-1] def selfPrime(num): count = 0 prime = 2 while True: # 如果能被2或者5除尽并且不是2或者5则prime+=1并且continue跳过本次循环使其不用判断是否为质数,提高效率 if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5): prime += 1 continue elif isPrime(prime) and palindrome(prime): count += 1 print(prime, end=" ") if count == num: break prime += 1 selfPrime(eval(input()))
成功的过了test5,只不过之后我还是不满意
第二次改进
def isPrime(num):
for i in range(3, int(num ** 0.5) + 1, 2):
if num % i == 0:
return False
return True
def palindrome(num):
return str(num) == str(num)[::-1]
def selfPrime(num):
count = 0
prime = 2
while True:
if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
prime += 1
continue
elif isPrime(prime) and palindrome(prime):
count += 1
print(prime, end=" ")
if prime == 2:
prime += 1
continue
if count == num:
break
prime += 2
selfPrime(eval(input()))
第二次改进是将判断质数的函数进行精简,对判断回文质数的地方进行改进
def isPrime(num): # 去掉了math,直接使用int(num ** 0.5)来替换,以此来精简代码 for i in range(3, int(num ** 0.5) + 1, 2): if num % i == 0: return False return True def palindrome(num): return str(num) == str(num)[::-1] def selfPrime(num): count = 0 prime = 2 while True: if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5): prime += 1 continue # 改成了elif elif isPrime(prime) and palindrome(prime): count += 1 print(prime, end=" ") # 如果prime是2就让prime+=1,其实只执行了一次 if prime == 2: prime += 1 continue if count == num: break # 最大的改进在这里,因为质数不可能是偶数,在prime=2那里使prime+=1后变成了3,后面每次都是prime+=2,以此来提高效率 prime += 2 selfPrime(eval(input()))
没想到只快了一点点,让我有些费解,但在后面也发现了问题所在
第三次改进
def isPrime(num):
for i in range(3, int(num ** 0.5) + 1, 2):
if num % i == 0:
return False
return True
def palindrome(num):
return str(num) == str(num)[::-1]
def selfPrime(num):
count = 0
prime = 2
while True:
if len(str(prime)) == 4:
prime += 9000
if len(str(prime)) == 6:
prime += 900000
if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
prime += 1
continue
elif isPrime(prime) and palindrome(prime):
count += 1
print(prime, end=" ")
if prime == 2:
prime += 1
continue
if count == num:
break
prime += 2
selfPrime(eval(input()))
在多次改进后,我发现没有4位数和6位数的回文质数,所以这次改进了判断回文质数
# 只要刚满1000变成4位数就直接+9000变成10000 if len(str(prime)) == 4: prime += 9000 # 同理直接+90w变成100w if len(str(prime)) == 6: prime += 900000
速度也大大增加了,但后面我又再次改进
第四次改进
def isPrime(num):
for i in range(3, int(num ** 0.5) + 1, 2):
if num % i == 0:
return False
return True
def palindrome(num):
return str(num) == str(num)[::-1]
def selfPrime(num):
count = 0
prime = 2
while True:
if len(str(prime)) == 4:
prime += 9000
if len(str(prime)) == 6:
prime += 900000
if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
prime += 1
continue
elif isPrime(prime) and palindrome(prime):
count += 1
print(prime, end=" ")
if prime == 2:
prime += 1
continue
if count == num:
break
if len(str(prime)) > 5:
prime += 4
continue
prime += 2
selfPrime(eval(input()))
# 仅仅改进了这里,只要位数大于5,实际上就是7以上,则每次都prime+=4,不再是+=2 if len(str(prime)) > 5: prime += 4 continue
3.最终版本
def isPrime(num):
for i in range(3, int(num ** 0.5) + 1, 2):
if num % i == 0:
return False
return True
def palindrome(num):
return str(num) == str(num)[::-1]
def selfPrime(num):
count = 0
prime = 2
while True:
if len(str(prime)) == 4:
prime += 9000
if len(str(prime)) == 6:
prime += 900000
if isPrime(prime) and palindrome(prime):
count += 1
print(prime, end=" ")
if prime == 2:
prime += 1
continue
if count == num:
break
if len(str(prime)) > 5:
prime += 10
continue
prime += 2
if __name__ == '__main__':
selfPrime(eval(input()))
在最后,发现百万级的每个回文质数都相差10倍数,所以就直接改成prime+=10
if len(str(prime)) > 5: # 改了这里 prime += 10 continue
速度又变快了不少同时还发现了下面这个代码有些多余
if (prime % 2 == 0 and prime != 2) or (prime % 5 == 0 and prime != 5):
prime += 1
continue
可能当时第二次改进就是这里导致速度只快了一点点
四、结语
其实在最后发现那个prime+=10只能过200w以前的回文素数,因为300w之后的是已3为结尾,再后面以1为结尾的则是1亿多的数字了,这也是我这个代码的问题所在,但过个现在这个pta还是没问题的