Project Euler 200

Project Euler 200

题目

Find the $200\text{th}$ prime-proof sqube containing the contiguous sub-string “$200$”

We shall define a sqube to be a number of the form, $p^2q^3$, where $p$ and $q$ are distinct primes.

For example, $200 = 5^2\times 2^3$ or $120072949 = 23^2\times 61^3$.
The first five squbes are $72, 108, 200, 392$, and $500$.

Interestingly, $200$ is also the first number for which you cannot change any single digit to make a prime; we shall call such numbers, prime-proof. The next prime-proof sqube which contains the contiguous sub-string “$200$” is $1992008$.

Find the $200\text{th}$ prime-proof sqube containing the contiguous sub-string “$200$”.

解决方案

令$Q=200$。由于本题所需要的质数上限比较难判定,所以使用的上限为$M=200000$。

从小到大枚举所有满足形如$p^2q^3$的数。本题通过之间产生的质数直接从小到大枚举。为保证每次枚举的值最小,使用了优先队列。

枚举时,为了避免枚举到$p=q$的情况,因此从一开始到整个的枚举过程,都需要保证$p< q$或者是$p>q$。此外,为了保证不重不漏,以$p< q$的情形为例:当$p=2$时,可以往右枚举$q$,也可以往下枚举$p$,但是,一旦$p$被枚举过,就不能再枚举$q$了。(枚举示意图如下)因为此时枚举$q$会导致大量的重复枚举,使程序运行很慢。

基于$p^2q^3$变一位是否为质数,这个直接调用库的算法判定。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from tools import is_prime, get_prime
from queue import PriorityQueue

Q = 200
M = 200000


def judge(n: int):
s = str(n)
l = len(s)
for i in range(l):
d = int(s[i])
for j in range(10):
if i + j == 0 or d == j:
continue
x = int(s[:i] + str(j) + s[i + 1:])
if is_prime(x):
return False
return True


q = PriorityQueue()
pr = get_prime(M)
q.put((pr[0] ** 2 * pr[1] ** 3, 0, 1))
q.put((pr[1] ** 2 * pr[0] ** 3, 1, 0))
cnt = 0
while True:
w, x, y = q.get()
if "200" in str(w) and judge(w):
cnt += 1
if cnt == Q:
ans = w
break
if x + 1 != y and not (x > y and y != 0):
q.put((pr[x + 1] ** 2 * pr[y] ** 3, x + 1, y))
if x != y + 1 and not (x < y and x != 0):
q.put((pr[x] ** 2 * pr[y + 1] ** 3, x, y + 1))

print(ans)

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
Ujimatsu Chiya 微信 微信
Ujimatsu Chiya 支付宝 支付宝