Project Euler 43

Project Euler 43

题目

Sub-string divisibility

The number, \(1406357289\), is a \(0\) to \(9\) pandigital number because it is made up of each of the digits \(0\) to \(9\) in some order, but it also has a rather interesting sub-string divisibility property.

Let \(d_1\) be the \(1\text{st}\) digit, \(d_2\) be the \(2\text{nd}\) digit, and so on. In this way, we note the following:

\(d_2d_3d_4=406\) is divisible by \(2\)
\(d_3d_4d_5=063\) is divisible by \(3\)
\(d_4d_5d_6=635\) is divisible by \(5\)
\(d_5d_6d_7=357\) is divisible by \(7\)
\(d_6d_7d_8=572\) is divisible by \(11\)
\(d_7d_8d_9=728\) is divisible by \(13\)
\(d_8d_9d_{10}=289\) is divisible by \(17\)

Find the sum of all \(0\) to \(9\) pandigital numbers with this property.

解决方案

可以直接用itertools库中的permutations产生所有置换,然后一个个直接进行判断。

比较一种优化的方法是自己手写深度优先搜索生成全排列,在恰当的地方及时剪枝,这将比上面的方法快不少。

代码

1
2
3
4
5
6
7
8
9
10
11
t = "0123456789"
ans = 0
for x in permutations(t):
s = "".join(x)
ok = 1
if int(s[1:4]) % 2 != 0 or int(s[2:5]) % 3 != 0 or int(s[3:6]) % 5 != 0 or int(s[4:7]) % 7 != 0 or \
int(s[5:8]) % 11 != 0 or int(s[6:9]) % 13 != 0 or int(s[7:10]) % 17 != 0:
ok = 0
if ok:
ans += int(s)
print(ans)
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
N = 10
vis = [0 for i in range(N)]
val = [0 for i in range(N)]
m = [2, 3, 5, 7, 11, 13, 17]
ans = 0


def dfs(f: int):
global ans
if f == 10:
ans += int("".join(str(x) for x in val))
return

for i in range(10):
if vis[i]:
continue
if f == 0 and i == 0:
continue
if f >= 3:
if (val[f - 2] * 100 + val[f - 1] * 10 + i) % m[f - 3] != 0:
continue
val[f] = i
vis[i] = True
dfs(f + 1)
vis[i] = False


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