鱼C论坛

 找回密码
 立即注册
查看: 3212|回复: 6

水仙花数问题求教

[复制链接]
发表于 2017-8-1 09:03:47 | 显示全部楼层 |阅读模式

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

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

x
如果一个3位数等于其各位数字的立方和,则称这个数位水仙花数。例如:153=1^3+5^3+3^3
  因此153就是一个水仙花数。
求100~999之间的所有水仙花数。

  1. for i in range(100, 1000):
  2.     sum = 0
  3.     temp = i
  4.     while temp:
  5.         sum = sum + (temp%10) ** 3   #问题1
  6.         temp //= 10         # 注意这里要使用地板除哦~  #问题2
  7.     if sum == i:
  8.         print(i)
复制代码


问题1:sum + (temp%10) ** 3    那么temp%10 取余数,也就是取个位数,然后求各位数的立方
           (这样理解对不对)
问题2:temp //= 10  返回商的整除部分给temp

最后的结果怎么就判断了sum == i
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2017-8-1 09:07:32 | 显示全部楼层
while temp:
        sum = sum + (temp%10) ** 3   #问题1
        temp //= 10     
这一段是分别取出了,个十百三位数字,并且立方以后计入sum中
才有了后面sum==i,这就是题目要求的“一个3位数等于其各位数字的立方和”的验证部分。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-1 09:25:58 | 显示全部楼层
明白了

while 循环后,第二次 sum + (temp%10) ** 3  取的是十位数
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-1 11:05:29 | 显示全部楼层
使用取余和地板除的方法确实刚开始接触不太理解,我刚开始也是一样。慢慢就懂了
不过我给你一个更好理解的语句:
注意:你需要懂列表解析(或者叫列表推导式)才行
代码:
  1. print([(x*100+y*10+z) for x in range(1,10) for y in range(10) for z in range(10) if (x**3+y**3+z**3==x*100+y*10+z)])
复制代码

结果:
  1. [153, 370, 371, 407]
复制代码

其实拆分出来是这样的(虽然看起来嵌套了很多层):
  1. for x in range(1,10):
  2.         for y in range(10):
  3.                 for z in range(10):
  4.                         if x**3+y**3+z**3==x*100+y*10+z:
  5.                                 print(x*100+y*10+z)
复制代码

结果:
153
370
371
407
个人觉得这样写代码的话,是直接从字面意思上翻译过来的,没有什么原理中转,更好理解些。当然小甲鱼老师的自然也不错,从美观的角度上看更胜一筹
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-1 11:46:27 | 显示全部楼层

  1. for i in range(100,1000):
  2.     if i == sum([int(j)**3 for j in str(i)]):
  3.         print(i)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-1 14:38:34 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2017-8-1 15:08 编辑

前面的解答都是正向解题,写了一个反向解题的方法,用了numpy数组。
对于很多题目来说,往往反向解题的速度比正向快得多,比如把这道题提升几个数量级,那正向解题的速度就会非常慢,而反向求解的过程是批量运算,速度会快得多。
  1. import numpy as np
  2. from numba import jit
  3. @jit
  4. def flower(N):
  5.         num = np.zeros(10**N, dtype='int64')
  6.         for i in range(10):
  7.                 for k in range(N):
  8.                         for j in range(i*10**k,1000,10**(k+1)):
  9.                                 num[j:j+10**k] += i**N
  10.         for i in range(10**(N-1),10**N):
  11.                 if i == num[i]:
  12.                         print(i)
  13. flower(3)
复制代码

153
370
371
407

用这个方法算10亿以下的所有水仙花数,只要8秒钟。
flower(9)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2017-8-1 14:53:33 | 显示全部楼层
首先  temp = i  是将 i 赋值给temp
while temp:
        sum = sum + (temp % 10) ** 3
        temp = temp // 10
这个循环就是求 i 这个数的三位数字的立方和并赋值给sum
然后判断sum是否等于i,如果相等,i 则为水仙花数
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-12-22 17:38

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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