Files

68 lines
2.4 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

欧拉计划第52题**排列倍数**)的答案是 **142857**
最快的数学计算方式基于以下**三大核心数学原理**的级联优化:
---
### 1. 位数约束原理(范围剪枝)
**数学基础**:若 $x$ 与 $6x$ 位数相同,则必须满足:
$$10^{n-1} \leq x < \frac{10^n}{6} \approx 1.666... \times 10^{n-1}$$
这直接排除了 $60\%$ 以上的搜索空间例如6位数时只需检查 $[100000, 166666)$ 区间而非 $[100000, 1000000)$。
---
### 2. 模9同余原理整除筛选
**数学基础**数字和与模9同余数根理论)。 $x$ $kx$ 是数字排列
$$\sum \text{digits}(x) \equiv x \pmod{9} \equiv kx \equiv \sum \text{digits}(kx) \pmod{9}$$
由此推出 $(k-1)x \equiv 0 \pmod{9}$。 $k=2$,得:
$$x \equiv 0 \pmod{9}$$
**关键优化**只需检查9的倍数搜索空间再缩减 $89\%$。
---
### 3. 规范形签名原理(排列判定)
**数学基础**两个数是排列 它们的**数字频数向量**Digit Histogram相同
不采用字符串排序$O(d \log d)$而是用**计数数组**作为规范签名$O(d)$
```python
def signature(n):
count = [0] * 10
while n:
count[n % 10] += 1
n //= 10
return tuple(count) # 如142857 → (1,1,1,1,1,1,0,1,0,0)的某种编码
```
---
### 最优算法实现Python
```python
def euler52():
n = 1
while True:
start = 10**(n-1)
# 核心约束x * 6 必须仍是n位数
end = int(10**n / 6) + 1
# 步长为9利用模9同余原理
for x in range((start + 8) // 9 * 9, end, 9):
sig = signature(x)
# 检查2x到6x是否共享相同签名
if all(signature(k * x) == sig for k in range(2, 7)):
return x
n += 1
# 结果142857即1/7的小数循环节
```
**复杂度**对于 $n$ 位数候选量从 $9 \times 10^{n-1}$ 降至约 $0.074 \times 10^{n-1}$配合 $O(n)$ 的签名比较可在**微秒级**求解
---
### 深层数学结构
**142857** 并非偶然它是**循环数**Cyclic Number $1/7 = 0.\overline{142857}$ 的小数展开密切相关其性质源于 $10$ 是模 $7$ 的原根导致 $2/7, 3/7...6/7$ 的循环节恰好是 $142857$ 的轮换排列