鱼C论坛

 找回密码
 立即注册
查看: 3150|回复: 15

题目44:找出最小的和与差都是五角数的五角数对

[复制链接]
发表于 2015-5-16 22:40:44 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Pentagon numbers

Pentagonal numbers are generated by the formula, BaiduShurufa_2015-5-16_22-33-49.png . The first ten pentagonal numbers are:

1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...

It can be seen that BaiduShurufa_2015-5-16_22-34-16.png . However, their difference, 70 − 22 = 48, is not pentagonal.

Find the pair of pentagonal numbers, BaiduShurufa_2015-5-16_22-34-51.png , for which their sum and difference are pentagonal and BaiduShurufa_2015-5-16_22-35-16.png is minimised; what is the value of D?

题目:

五角数通过如下公式定义: BaiduShurufa_2015-5-16_22-33-49.png 。前十个五角数是:

1, 5, 12, 22, 35, 51, 70, 92, 117, 145, ...

可以看出 BaiduShurufa_2015-5-16_22-34-16.png . 但是它们的差 70 − 22 = 48 却不是五角数。

找出最小的五角数对 BaiduShurufa_2015-5-16_22-34-51.png , 使得它们的和与差都是五角数,并且 BaiduShurufa_2015-5-16_22-35-16.png 取到最小。这时 D 的值是多少?

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-8-30 18:05:30 | 显示全部楼层
看不懂。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-6 10:40:30 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-10-12 14:07 编辑

Find: P1:7042750,P2:1560090,D:5482660,S:8602840


  1. def isRoot(x):        #根的求解方程,判别是否是整数
  2.     if (1+(1+24*x)**0.5) % 6 == 0:
  3.         return 1
  4.     else:
  5.         return 0

  6. for i in range(1,10000):
  7.     P1 = int(i*(3*i-1)/2)        
  8.     for j in range(i,1,-1):
  9.         P2 = int(j*(3*j-1)/2)        
  10.         if isRoot(P1+P2) and isRoot(P1-P2):
  11.             print ('Find: P1:%d,P2:%d,D:%d,S:%d' % (P1,P2,P1-P2,P1+P2))
  12.             exit()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-12 14:17:33 | 显示全部楼层
利用set()元组去搜索,更快速 0.3 sec出结果
  1. from time import time
  2. start = time()

  3. def generatePentagonals(n):
  4.     pentagonals = [0]
  5.     x=1
  6.     while pentagonals[len(pentagonals)-1] < n:
  7.         pentagonals.append(x*(3*x-1)/2)
  8.         x+=1
  9.     pentagonals.pop(0)
  10.     return pentagonals


  11. def findPair(p):
  12.     pSet = set(p)

  13.     for i in range (1,len(p)):
  14.         for j in range(0,i):
  15.             if (p[i]-p[j] in pSet) and (p[i]+p[j] in pSet):
  16.                 return p[i] - p[j]
  17.                

  18.     return "Pair not in range"

  19.    
  20. print (findPair(generatePentagonals(10000000)))

  21. print("Time: {0} secs".format(time()-start))
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-10-25 18:59:03 | 显示全部楼层
  1. def progrem44():
  2.     s = set(i*(3*i-1)//2 for i in range(1,2501))
  3.     for i in s:
  4.         for j in s:
  5.             if i < j: continue
  6.             if i+j in s and i+2*j in s:
  7.                 return j,i+j
  8. print(progrem44())
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-1-16 09:45:58 | 显示全部楼层
没有好办法,学习4楼老大代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-5 22:55:02 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2020-7-2 18:26 编辑
  1. def Pentagon(n):
  2.     numbers = n*(3*n-1)/2
  3.     return numbers


  4. def Judg(x, i):
  5.     for n in range(1, 2*i-1):
  6.         if x == n*(3*n-1)/2:
  7.             return True
  8.     return False


  9. i = 2
  10. temps = True

  11. while temps:
  12.     for n in range(1, i):
  13.         temp = Pentagon(i) - Pentagon(n)
  14.         tmp = Pentagon(i) + Pentagon(n)
  15.         if Judg(temp, i) and Judg(tmp, i):
  16.             print(temp)
  17.             temps = False

  18.     i += 1
复制代码
能算出来,但是速度很慢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-6-13 09:20:00 | 显示全部楼层
本帖最后由 渡风 于 2017-6-13 09:33 编辑

%% Problem44.m
%最后编辑时间:2017-06-13 9:21 版本1.0
%找出 两个五角星数,使得它们的和为五角星数,差为五角星数且为最小
% Problem44所用时间为28.294秒
% Problem44的答案为5482660
  1. %% Problem44.m
  2. %最后编辑时间:2017-06-13 9:21 版本1.0
  3. %找出 两个五角星数,使得它们的和为五角星数,差为五角星数且为最小
  4. % Problem44所用时间为28.294秒
  5. % Problem44的答案为5482660
  6. function Output = Problem44()
  7. tic

  8. Start = 3;
  9. Meet = 0;
  10. while (Meet == 0)
  11.     Bignum = (Start * (3*Start - 1))/2;
  12.     for ii = Start - 1: -1 : 1
  13.         Smallnum = (ii * (3*ii - 1))/2;
  14.         if IsPentagon(Bignum - Smallnum) == 1 && IsPentagon(Bignum + Smallnum) == 1
  15.             Meet = 1;
  16.             break
  17.         end
  18.     end
  19.     Start = Start + 1;
  20.     disp(Start)
  21. end

  22. Output = Bignum - Smallnum;
  23. toc
  24. disp('此代码使用matlab编程')
  25. disp(['Problem44所用时间为',num2str(toc),'秒'])
  26. disp(['Problem44的答案为',num2str(Output)])
  27. end
  28. %% IsPentagon.m
  29. % 测试一个数是否为五角星
  30. % 最后编辑时间:17-06-13 9:03 版本:1.0
  31. % 是五角型数则返回 1,否则返回 0
  32. function Judge = IsPentagon(n)
  33. if nargin == 0
  34. n = 22;
  35. end
  36. if n == 1
  37.     Judge = 1;
  38. else
  39.     front = floor(sqrt(2*n)/2);
  40.     after = ceil(sqrt(2*n)/1.7);
  41.     Judge = 0;
  42.     for ii = after:-1:front
  43.         if n == ((3*ii - 1) * ii)/2
  44.             Judge = 1;
  45.             break
  46.         end
  47.     end
  48. end
  49. end
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-18 23:24:12 | 显示全部楼层
  1. import time
  2. s=time.clock()
  3. from itertools import takewhile
  4. def pentagon(init=None):
  5.     if init is None:
  6.         init=1
  7.     while not ispentagon(init):
  8.         init+=1
  9.     n=((1+24*init)**0.5+1)//6
  10.     while True:
  11.         yield n*(3*n-1)//2
  12.         n+=1

  13. def ispentagon(n):
  14.     flag=False
  15.     if int(((1+24*n)**0.5+1)/6)==((1+24*n)**0.5+1)/6:
  16.         flag=True
  17.     return flag

  18. flag=False
  19. for p1 in pentagon(3):
  20.     if flag==True:
  21.         break
  22.     for p2 in takewhile(lambda x:x<p1,pentagon(1)):
  23.         if ispentagon(p1+p2) and ispentagon(p1-p2):
  24.             print(int(p1-p2))
  25.             flag=True
  26.             break
  27. print('Runing time: {0}s'.format(round(time.clock()-s,3)))
复制代码

5482660
Runing time: 3.316s
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-9-30 10:51:29 | 显示全部楼层
用的matlab
结果是:
>> Untitled
     7042750

     1560090

     5482660

时间已过 0.167725 秒。
>>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-6-21 10:41:54 | 显示全部楼层
最小值是:442.0
用时:0.7488047999999999秒

import math
import time


def pentagon_num(num):
    if int(math.sqrt(24*num + 1)) == math.sqrt(24*num + 1):
        return True


def cal_result():
    result = []
    #  2000的五角数范围已经达到 1000 * (2999)/2 = 1499500
    for i in range(2, 1000):
        for j in range(1, i):
            if pentagon_num(i*(3*i-1)/2 + j*(3*j-1)/2) and pentagon_num(i*(3*i-1)/2 - j*(3*j-1)/2):
                result.append(i*(3*i-1)/2 - j*(3*j-1)/2)
    return result

print("最小值是:{}\n用时:{}秒".format(min(cal_result()), time.process_time()))
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 0 反对 1

使用道具 举报

发表于 2019-8-5 13:13:24 | 显示全部楼层
本帖最后由 永恒的蓝色梦想 于 2020-5-8 08:26 编辑

抄了一下3L的求根公式:
  1. isRoot=lambda x:not(1+(1+24*abs(x))**0.5)%6
  2. pentagon=lambda x:(3*x-1)*x//2
  3. for k in range(1,10000):
  4.   i=pentagon(k)
  5.   for j in range(k,10000):
  6.     j=pentagon(j)
  7.     if isRoot(i-j)and isRoot(i+j):
  8.       print(f'运行结果:{abs(i-j)}\n运行时间:{t()-t1}s')
  9.       exit()
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-8-18 19:51:50 | 显示全部楼层
5482660

Process returned 0 (0x0)   execution time : 1.176 s
Press any key to continue.
纯暴力解法。不妨设Pj>Pk
先枚举D,再枚举Pk,二分查找
D小于P[k+1] - P[k]时枚举下一个D
  1. #include<iostream>
  2. #include<algorithm>
  3. using namespace std;

  4. const int M = 3e3;
  5. int p[M] = {0,1};

  6. void ini(){
  7.   for (int i = 2;i < M;i++){
  8.     p[i] = p[i-1] + 3*i - 2;
  9.   }
  10. }

  11. void print(int n){
  12.   for (int i = 1;i < n;i++){
  13.     cout << p[i] << endl;
  14.   }
  15. }

  16. int main(){
  17.   ini();

  18.   for (int a = 2;;a++){
  19.     for (int k = 1;k+1 < M && p[k+1] - p[k] <= p[a];k++){
  20.       if (!binary_search(p, p+M, p[a] + p[k]))  continue;
  21.       if (!binary_search(p, p+M, p[a] + 2*p[k]))  continue;
  22.       cout << p[a] << endl;
  23.       return 0;
  24.     }
  25.   }

  26.   return 0;
  27. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-3-20 17:08:59 | 显示全部楼层
  1. #include <stdio.h>
  2. #include <math.h>

  3. int check_Pentagonal(int);
  4. int check_Pentagonal(int num)
  5. {

  6.         if (num == 0)
  7.         {
  8.                 return 0;
  9.         }
  10.         float j;
  11.         int i;
  12.         j = (sqrt(24 * num + 1) + 1) / 6;
  13.         i = (sqrt(24 * num + 1) + 1) / 6;

  14.         if ((float)i == j)
  15.         {
  16.                 return 1;
  17.         }
  18.         else
  19.         {
  20.                 return 0;
  21.         }
  22. }

  23. main()
  24. {
  25.         int i, j, m, n;
  26.        
  27.         for (i = 2; i < 10000; i++)
  28.         {
  29.                 for (j = i; j >= 1; j--)
  30.                 {
  31.                         m = i * (i * 3 - 1) / 2;
  32.                         n = j * (j * 3 - 1) / 2;
  33.                         if (check_Pentagonal(m + n))
  34.                         {
  35.                                 if (check_Pentagonal(m - n))
  36.                                 {
  37.                                         goto Label;
  38.                                 }
  39.                         }
  40.                 }
  41.         }
  42. Label:printf("Pj = %d, Pk = %d D = %d", m, n, m - n);
  43. }
复制代码


Pj = 1560090, Pk = 7042750 D = 5482660
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-1-8 00:28:30 | 显示全部楼层
本帖最后由 guosl 于 2022-1-8 00:30 编辑
  1. /*
  2. 答案:5482660
  3. 耗时:2.34444秒(单核)
  4.       0.198174秒(八核)
  5. */
  6. #include <iostream>
  7. #include <vector>
  8. #include <algorithm>
  9. #include <omp.h>

  10. using namespace std;

  11. int main(void)
  12. {
  13.   //打表
  14.   vector<int> v;
  15.   int k = 1;
  16.   while (true)
  17.   {
  18.     int p = k * (3 * k - 1) / 2;
  19.     if (p < 1000000000)
  20.     {
  21.       v.push_back(p);
  22.       ++k;
  23.     }
  24.     else
  25.       break;
  26.   }
  27.   int nMinD = 0x7fffffff, nK = int(v.size());
  28.   volatile int i = 0;
  29.   volatile bool bContinue = true;
  30. #pragma omp parallel firstprivate(nK) shared(i,v,bContinue) reduction(min:nMinD)
  31.   while (bContinue && i < nK)
  32.   {
  33.     int nD;
  34. #pragma omp critical(c1)
  35.     nD = v[i++];//枚举差
  36.     bool bFind = false;
  37.     for (int j = 0; j < nK; ++j)
  38.     {
  39.       auto itr = lower_bound(v.begin(), v.end(), nD + v[j]);
  40.       if (itr != v.end() && *itr == nD + v[j])//找到两个五边形数使其差位nD
  41.       {
  42.         int k = int(itr - v.begin());
  43.         int nD1 = v[k] + v[j];
  44.         itr = lower_bound(v.begin(), v.end(), nD1);
  45.         if (itr != v.end() && *itr == nD1)//找到两个五边形数使其和与差都是五边形数
  46.         {
  47.           bFind = true;
  48.           break;
  49.         }
  50.       }
  51.     }
  52.     if (bFind)
  53.     {
  54.       nMinD = min(nD, nMinD);//记录最后结果
  55. #pragma omp critical(c2)
  56.       bContinue = false;
  57.     }
  58.   }
  59.   cout << nMinD << endl;
  60.   return 0;
  61. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-10-24 22:21:27 | 显示全部楼层
  1. import time as t
  2. import numpy as np

  3. start = t.perf_counter()


  4. def is_integer(a_num):
  5.     delta = 0.00001
  6.     if abs(a_num - int(a_num)) < delta:
  7.         return True


  8. def find_pentagon():
  9.     given_range = 3000
  10.     for j in range(1000, given_range):
  11.         for k in range(j + 2, given_range + 2):
  12.             k_add_j = np.sqrt(np.square(k) + np.square(j) - 1 / 3 * (k + j) + 1 / 36) + 1 / 6
  13.             k_minus_j = np.sqrt(np.square(k) - np.square(j) - 1 / 3 * (k - j) + 1 / 36) + 1 / 6
  14.             if is_integer(k_add_j) and is_integer(k_minus_j):
  15.                 return [j, k, k_minus_j]


  16. nums = find_pentagon()
  17. print(nums[2] * (3 * nums[2] - 1) / 2)
  18. print("It costs %f s" % (t.perf_counter() - start))
复制代码



5482660.0
It costs 0.448183 s
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 02:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表