Project-Euler-045思维

045题:

题意:

​ 三角形数、五边形数和六角形数分别由以下公式给出:

三角形数Tn=n(n+1)/21, 3, 6, 10, 15, …
五边形数Pn=n(3n−1)/21, 5, 12, 22, 35, …
六边形数Hn=n(2n−1)1, 6, 15, 28, 45, …

​ 可以验证,T285 = P165 = H143 = 40755。

​ 找出下一个同时是三角形数、五边形数和六角形数的数

思路:

​ 由于六边形增长速度最快,所以我们优先根据公式遍历六边形数。然后我们看一下三角形数,把n = 2k - 1带入公式,得到Tk = k(2k - 1),所以,每下角标为2n - 1的三角形数都是六边形数,也就是说是六边形数,一定也是三角形数

​ 因此我们只需要判断六边形数是否为五边形数即可,找到第一个就返回

​ 有以下三个想法判断是否为五边形数:

​ 1.先预处理出前10000个五边形数(应该不会超过这些),然后利用map<long long, bool>zcy映射一下这些五边形数,然后从144开始遍历六边形数,只要zcy[六边形数]存在就直接输出,时间复杂度O(m + n),其中m为预处理的五边形数的个数

​ 2.外层for循环从144开始遍历六边形数,然后利用二分五边形数下角标查找是否存在对应的五边形数,若存在则返回并输出,时间复杂度O(n * logn)

​ 3.for循环从144开始遍历六边形数,设得到的数设为t,我们求n(3n−1)/2 = t 的正整数解,也就是n = (1 + sqrt(1 + 24t)) / 6,若n为正整数则该数也为五边形数,时间复杂度O(n)

代码:

​ 老规矩上时间复杂度最低的:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <inttypes.h>
#include <map>
#include <algorithm>
#define ll int64_t
#define d int32_t
#define f double
#define r return
#define mem(a) memset(a, 0, sizeof(a));
using namespace std;

//六边形公式
ll g(ll a) {
    r a * (2 * a - 1); 	
}

//判断该六边形数g(a)是否为五边形数
bool chooes(ll a) {
    ll t = g(a);
    f inx = (sqrt(24 * t + 1) + 1 ) / 6;
    if (inx == (ll)inx) return true;
    r false;
}

d main () {
    for (ll i = 144; ; i++) {
        if (chooes(i)) {
            printf("%" PRId64"\n", g(i));
            break;
        }
    }
    r 0;
}

最后答案为:1533776805

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值