大致翻译:
五边形数由公式Pn=n(3n−1)/2生成。前十个五边形数为:
1、5、12、22、35、51、70、92、117、145…
可以看出,P4 + P7 = 22 + 70 = 92 = P8。然而,它们的差异70-22=48不是五边形数。
找到一对五边形数Pj和Pk,使它们的和与差都是五边形数,并且D = |Pk − Pj|最小;D的值是多少?
思路:
在五边形数序列中从小到大枚举D, 并判断是否存在
P
l
P_l
Pl,
P
r
P_r
Pr满足
P
l
+
D
=
P
r
P_l+D=P_r
Pl+D=Pr, 且
P
l
+
P
r
∈
{
P
k
∣
k
∈
N
+
}
P_l+P_r \in \{P_k| k \in N^+ \}
Pl+Pr∈{Pk∣k∈N+},可以用滑动窗口来找这样的
P
l
P_l
Pl和
P
r
P_r
Pr.
typedef long long ll;
ll P[1000005];
ll fun() {
int n = 1e6;//设在前1000000个五边形数中能找到满足条件的D,若找不到则扩大搜索范围
for (int i = 1; i <= n; i++)
P[i] = 1LL * i * (3 * i - 1) / 2;
for (ll i = 1, D = P[i]; i <= n; D = P[++i]) {
for (int l = 1, r = 1;; l++) {
while (r <= n && P[r] - P[l] < D)
r++;
if (r <= n && P[r] - P[l] == D && *lower_bound(P + r, P + n + 1, P[r] + P[l]) == P[r] + P[l])
return D;
if (r == l + 1)//之后的五边形数序列相邻数间隔>D
break;
}
}
return -1;//当前搜索范围找不到满足条件的D
}