鱼C论坛

 找回密码
 立即注册
查看: 3506|回复: 9

[技术交流] 小练习:找出最小的立方数,使得它各位的排列中五个是立方数

[复制链接]
发表于 2017-2-26 21:02:46 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 冬雪雪冬 于 2017-3-10 09:47 编辑

从现在开始我们要开展一批欧拉计划的习题练习。
其实在我们论坛中已有欧拉计划的板块,可能有些鱼油还没注意到。
什么是欧拉计划:http://bbs.fishc.com/thread-60405-1-1.html
我们欧拉板块现已给出了200余题,这批练习将从欧拉计划中选题。其实用python语言完成有很多的优势,可以更简洁更方便的实现。
如果大家有兴趣也可浏览欧拉的英文网站:https://projecteuler.net/archives
这里已经有了500余题。


                               
登录/注册后可看大图


题目要求:
以python语言完成,如果是python2请注明。
程序以代码文字格式发帖。
注重程序效率和创意。
答题在一周内完成,即3.6 10:00之前,其后将公开大家的答案,并评比成绩。

另程序和答案可以在网上搜到,希望大家独立完成。题目不难,大家看看谁的效率高。

----回帖需写明解题思路,鼓励在程序



题目:

立方数 41063625

                               
登录/注册后可看大图
通过排列可以得到两个另外的立方数: 56623104

                               
登录/注册后可看大图
和 66430125

                               
登录/注册后可看大图
。 实际上 41063625 是最小的三个(不多不少)排列是立方数的立方数。

找出最小的立方数,其五个(不多不少)排列是立方数。

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

使用道具 举报

发表于 2017-2-26 21:19:44 | 显示全部楼层
  1. i = 1
  2. cube_dict = {}
  3. while 1:
  4.     i3 = pow(i, 3)
  5.     digit_list = [j for j in str(i3)]
  6.     digit_list.sort()
  7.     digit_str = ''.join(digit_list)
  8.     if digit_str in cube_dict:
  9.         n = cube_dict[digit_str][0]
  10.         if n == 4:
  11.             break
  12.         l = cube_dict[digit_str][1]
  13.         l.append(i)
  14.         cube_dict[digit_str] = (n + 1, l)        
  15.     else:
  16.         cube_dict[digit_str] = (1, [i])
  17.     i += 1
  18. print(cube_dict[digit_str][1][0])
复制代码


应该没问题~热爱鱼C~

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-2-27 08:44:29 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-2-27 08:45 编辑

这题很简单,就是暴力破解,先计算每个数的立方数,然后把这个立方数sorted排序后以字典形式保存,当字典中某个value的长度为5时,则表示找到了答案。
源码:
  1. # -*- coding: utf-8 -*-
  2. import time
  3. start = time.time()
  4. D,i = {},1
  5. while True:
  6.     tri = i**3
  7.     key = ''.join(sorted(list(str(tri))))
  8.     value = D.get(key, [])
  9.     value.append(i)
  10.     D[key] = value
  11.     if len(value)== 5:
  12.         print (value)
  13.         break
  14.     i += 1
  15. print('Time used: %.3f sec' % (time.time()-start))
复制代码

输出:
[5027, 7061, 7202, 8288, 8384]
Time used: 0.029 sec

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-2-27 15:34:33 | 显示全部楼层
  1. # encoding:utf-8
  2. # 找出最小的立方数,使得它各位的排列中五个是立方数
  3. from time import time
  4. def getNums(N=100):
  5.     n, l_nums, l_result = 5000, [], []
  6.     while True:
  7.         tmp = sorted(str(n ** 3))
  8.         l_nums.append(tmp)
  9.         l_result.append(n)
  10.         if l_nums.count(tmp) == 5:
  11.             while l_nums.count(tmp) > 0:
  12.                 print(l_result[l_nums.index(tmp)])
  13.                 l_result.remove(l_result[l_nums.index(tmp)])
  14.                 l_nums.remove(tmp)   
  15.             break
  16.         n += 1
  17. if __name__ == '__main__':
  18.     start = time()
  19.     getNums()
  20.     print('cost %.6f sec' % (time() - start))
复制代码


5027
7061
7202
8288
8384
cost 0.340000 sec

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-2-28 03:35:17 | 显示全部楼层
本帖最后由 wangzhenas 于 2017-3-5 20:10 编辑

答案:127035954683
耗时: 0.04s
i5-3210M

思路就是把立方数转化为整理过的元组,元祖可作为字典的key,然后对对应的value(list)做append操作根据,value的长度来判断是否满足条件
循环条件是立方数的位数是否有变化,如果变大了,那么就重置字典
比如2的3次是8,3的3次是27那么就做一次判断是否有满足条件的值,如果没有的话就重置字典

  1. import time
  2. t = time.time()

  3. num, current_len, d = 0, 0, {}

  4. while 1:
  5.     cubic_num_s = tuple(sorted(str(num**3)))
  6.     if len(cubic_num_s) > current_len:
  7.         check_list = [min(value) for value in d.values() if len(value) == 5]
  8.         if check_list:
  9.             print(check_list,min(check_list)**3,time.time()-t)
  10.             break        
  11.         d, current_len = {cubic_num_s:[num]}, len(cubic_num_s)
  12.     elif cubic_num_s in d:
  13.         d[cubic_num_s].append(num)
  14.     else:
  15.         d.update({cubic_num_s:[num]})
  16.     last_num_s, num = cubic_num_s, num+1
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-2-28 11:50:27 | 显示全部楼层
算出来立方数直接拆开排序存到数组,然后与之前存的数比较,,找够5个就完事了
  1. import time
  2. start = time.time()
  3. resultlen=5
  4. num=1
  5. lennum=0
  6. lifangshulist=[]
  7. result=0
  8. while lennum!=resultlen:
  9.         resultlist=[]
  10.         lennum=0
  11.         lifangshu=list(str(num*num*num))
  12.         lifangshu.sort()
  13.         lifangshulist.append((lifangshu))
  14.         for i,oldnum in enumerate(lifangshulist[::-1]):
  15.                 if (lifangshu==oldnum):
  16.                         result=i
  17.                         resultlist.append(oldnum)
  18.                         lennum+=1
  19.         num+=1
  20. print ((num-result-1)**3)
  21. print('BFS--Time used: %.3f sec' % (time.time()-start))
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-2-28 16:01:00 | 显示全部楼层
本帖最后由 飘飞的白杨 于 2017-2-28 18:48 编辑

使用数组储存排序后的“数”,统计个数
  1. from time import time
  2. ttt = time()
  3. def program_62():
  4.     n, s = 345, []
  5.     while True:
  6.         temp = sorted(str(n**3))
  7.         s.append(temp)
  8.         if s.count(temp) == 5:
  9.             return [i+345 for i in range(len(s)) if s[i] == temp]
  10.         n += 1
  11. print(program_62(), time()-ttt)
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-3-1 14:31:11 | 显示全部楼层
用的方法比较死,算出来的数放入列表并排序,排序结果没有在jieguo里那就添加进去,并添加原数ys,为了让ys能把5个数都记录下来ys添加的是列表,cs列表记录结果中对应位置出现的次数。一旦cs[x]=5,就显示出ys[x][0]**3的结果,实际ys[x]里就是5个数字,本题中是[5027, 7061, 7202, 8288, 8384]
  1. jieguo=[]
  2. ys=[]
  3. cs=[]
  4. for i in range(1000,10000):
  5.     x=list(str(i**3))
  6.     x.sort()
  7.     if x in jieguo:
  8.         cs[jieguo.index(x)]+=1
  9.         ys[jieguo.index(x)].append(i)
  10.         if cs[jieguo.index(x)]==5:
  11.             print(ys[jieguo.index(x)][0]**3)
  12.             break
  13.     else:
  14.         jieguo.append(x)
  15.         ys.append([i])
  16.         cs.append(1)
复制代码

  1. == RESTART: C:\Users\ASUS\AppData\Local\Programs\Python\Python35-32\test.py ==
  2. 127035954683
  3. >>>
复制代码

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-3-2 09:21:41 | 显示全部楼层
  1. #!/usr/bin/env python
  2. # -*- coding: UTF-8 -*-
  3. #python2.7
  4. import time
  5. tmp ={}
  6. j = 0
  7. start = time.time()
  8. while 1:
  9.         i = ''.join(sorted(str(j**3)))
  10.         if tmp.has_key(i):
  11.                 tmp[i]['cnt'] = tmp[i]['cnt']+1
  12.                 tmp[i]['list'].append(j)
  13.         else:
  14.                 tmp[i]  = {'cnt':1,'list':[j]}
  15.         if tmp[i]['cnt']==5:
  16.                 print 'sec:',time.time()-start
  17.                 print 'result num is:',(tmp[i]['list'][0])**3
  18.                 print 'result list:',tmp[i]['list']
  19.                 break
  20.         j = j+1
复制代码



sec: 0.023540019989
result num is: 127035954683
result list: [5027, 7061, 7202, 8288, 8384]

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

发表于 2017-3-2 09:49:15 | 显示全部楼层
from time import time

"""
思路 先在100-10000以内 查找数据
先建立x,y列表 分别存储100-10000和对应的立方数
"""
st=time()
x=[i  for i in range(101,10000)]
y=list(map(lambda x:x**3,x))

def f(n):#定义一个数字排序函数
    u=[]
    for j in str(n):
        u.append(j)
    u1=sorted(u,key=int)
    v=''.join(u1)
    return v

z=list(map(lambda x:f(x),y))#利用排序函数对y各个元素处理
z1=sorted(z)#然后对处理后的列表进行排序,把数字相同的元素排在一起


for k in range(0,len(z1)-5):#以每5个元素 取数
    k1=z1[k:k+5]
    if k1[0]==k1[1]==k1[2]==k1[3]==k1[4]:#如果5个元素都相同,就找到了要求的数字
        print(k)
        print(z1[k:k+5])
        u=z1[k:k+5][0]
        print(u)
        break

ww=[]
for  m1,m2 in enumerate(z):#这步是为了找到要求元素的索引
    if m2==u:
        ww.append(m1)
print(ww)

li=[]
for ind in ww:#把索引带入x 就找到对应的立方根数了
    li.append(x[ind])
print(li)
print(time()-st)

结果
[5027, 7061, 7202, 8288, 8384]
0.171875

评分

参与人数 1荣誉 +10 鱼币 +10 收起 理由
冬雪雪冬 + 10 + 10

查看全部评分

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-24 08:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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