Problem 44: Pentagon numbers

题目:
在这里插入图片描述

大致翻译:

五边形数由公式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{PkkN+},可以用滑动窗口来找这样的 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
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值