鱼C论坛

 找回密码
 立即注册
查看: 5901|回复: 7

[技术交流] 14 - 数之吟唱:黑洞数

[复制链接]
发表于 2021-7-11 20:15:49 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 鱼C-小师妹 于 2021-8-6 20:16 编辑




                               
登录/注册后可看大图


黑洞数又称陷阱数,是指:

任何一个数字不全相同的整数,在经过有限次“重排求差”操作后,总会得到某一个或一些数,这些数即为黑洞数。

“重排求差”操作是将组成一个数的各位数字重排,将得到的最大数减去最小数。

例如,207 的“重排求差”操作序列是:720-027=693,963-369=594,954-459=495,此时再进行“重排求差”操作不会发生改变。

再用 208 计算一次:820-028=792,972-279=693,963-369=594,954-459=495。

也是停止到 495,所以 495 是三位黑洞数。

根据上面的操作,我们知道对于任意一个数字不全相同的整数,最后结果总会入到一个黑洞圈或黑洞数里。

最后结果一旦为黑洞数,无论再重复进行多少次的“重排求差”操作,结果都是一样的。

因此可把结果相等作为判断“黑洞数”的依据。

我们现在通过编程来找出所有三位数的“黑洞数”。

这次就不带大家画流程图了,直接上算法设计

可以讲算法设计理解为文字版的流程图,也是设计“过程”。

步骤:

  • 将任意一个三位数进行拆分
  • 拆分后的数据重新组合,将可以组合的最大值减去最小值,差值赋给变量 j
  • 将当前差值暂存到另一变量h中:h=j
  • 对变量 j 执行拆分、重组、求差操作,差值仍然存储到变量 j 中
  • 判断当前差值 j 是否与前一次的差值 h 相等,若相等,则将差值输出并结束循环,否则重复步骤 3~5

关键其实就是求出拆分后所能组成的最大值 max 和最小值 min。

求最大值和最小值的关键是找出拆分后数值的大小关系,通过比较找出最大值、次大值及最小值。

三个数比较大小可以采用两两比较的方法,首先 a 与 b 比较,其次 a 与 c 比较,最后 b 与 c 比较。

比较顺序很重要,有时比较顺序不一样得到的结果也是不一样的。

在比较过程中如需对两个数进行交换,则需借助中间变量 t 来实现,否则变量中存储的数将被改变。

假如这么写:

  1. a=b
  2. b=a
复制代码

第一个语句执行完毕后变量 a 的值由原值变为 b 的值,第二个语句的作用是把现在 a 的值赋给 b。

但此时 a 中存储的已经不再是原来的值,而是被赋予的 b 值。

比较后数值按照从大到小的顺序分别存储在变量 a、b、c 中,再按一定的顺序重新组合成最大值和最小值。

因求最大值和最小值的操作在程序中不止一次用到,故可定义两个函数 three_max(a,b,c) 和 three_min(a,b,c)。

功能分别是求由三个数组成的最大值和最小值,a、b、c 分别对应百位、十位、个位。

代码如下:

  1. def three_max(a, b, c):
  2.     # a、b、c分别对应百位、十位、个位
  3.     if a < b:
  4.         # 如果a<b,则将变量a、b的值互换
  5.         t = a
  6.         a = b
  7.         b = t
  8.     if a < c:
  9.         t = a
  10.         a = c
  11.         c = t
  12.     if b < c:
  13.         t = b
  14.         b = c
  15.         c = t
  16.     return a*100 + b*10 + c
复制代码

函数 three_min(a,b,c) 的代码与以上代码的不同之处在于最后的返回值。

函数 three_min(a,b,c) 中需返回的是最小值 c*100+b*10+a 。

将第一次得到的差值 j 赋给变量 h,因在后面的编程过程中会再次将得到的差值赋给变量 j。

为避免 j 中存储的原值找不到,故先把前一次的差值暂存到另一个变量 h 中。

在比较过程中一旦两次结果相等,循环过程即可结束,可用 break 语句实现。

判定条件 j==h 可以在循环体中用 if 语句实现,也可写在 while 语句中。

通过 def 就可以自定义函数,在需要的地方调用就好。

寻找“黑洞数”的方法代码如下:

  1. def black_number(max, min):
  2.     j = max - min
  3.     while min < max:   
  4.         h = j  # h记录上一次最大值与最小值的差
  5.         hun = j // 100    # 百位
  6.         ten = j % 100 // 10  # 十位
  7.         bit = j % 10  # 个位
  8.         max = three_max(hun, ten, bit)      # 最大值
  9.         min = three_min(hun, ten, bit)      # 最小值
  10.         j = max - min
  11.         if j == h:  # 最后两次差相等时,差即为所求黑洞数
  12.             print("黑洞数=",j)
  13.             break # 跳出循环
复制代码

核心代码就是如此,我们来运行下:

2021-07-19_17-01-44.jpg

剩下的就是提醒用户输入的代码啦,完整代码当课后作业留给大家啦,下课!

源码: 13BlackNumber.zip (740 Bytes, 下载次数: 19, 售价: 8 鱼币)

评分

参与人数 1荣誉 +5 贡献 +3 收起 理由
睦ちゃん她爹 + 5 + 3 鱼C有你更精彩^_^

查看全部评分

本帖被以下淘专辑推荐:

小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-7-11 21:04:54 From FishC Mobile | 显示全部楼层
只会暴力
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-12 14:25:52 | 显示全部楼层
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-7 20:34:38 | 显示全部楼层
视频更新咯
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-8-22 18:50:54 | 显示全部楼层

这代码 没有灵魂哇!
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-8 20:32:05 | 显示全部楼层
小甲鱼的新视频还没更新到函数呢,所以用列表写的,有点复杂呀!
  1. n = int(input('请输入一个三位数:'))
  2. a = n % 10
  3. b = (n // 10) % 10
  4. c = n // 100
  5. rhyme = [a,b,c]
  6. rhymemin =rhyme.copy()
  7. rhymemin.sort()
  8. rhymemax = rhyme.copy()
  9. rhymemax.sort(reverse = True)
  10. h = rhymemax[0]*100 + rhymemax[1]*10 + rhymemax[2]
  11. l = rhymemin[0]*100 + rhymemin[1]*10 + rhymemin[2]
  12. j = h - l
  13. while h > l:
  14.     m = j
  15.     m1 = m % 10
  16.     m2 = (m // 10) % 10
  17.     m3 = m // 100
  18.     me = [m1,m2,m3]
  19.     memin = me.copy()
  20.     memin.sort()
  21.     memax = me.copy()
  22.     memax.sort(reverse = True)
  23.     mh = memax[0]*100 + memax[1]*10 + memax[2]
  24.     ml = memin[0]*100 + memin[1]*10 + memin[2]
  25.     j = mh - ml
  26.     if j == m:
  27.         print(f'黑洞数为{j}')
  28.         break
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-8 22:29:11 | 显示全部楼层
keypoint:前后两次差值结果相同
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-11-14 16:09:34 | 显示全部楼层
#黑洞数:

def Three_maximin(n):
    a,b,c=n//100,n//10%10,n%10
    if a < b:
        a,b = b,a
    if a < c:
        a,c = c,a
    if b < c:
        b,c = c,b
    return a*100+b*10+c,c*100+b*10+a

def Black_number(max,min):
    j = max-min
    while min < max:
        h = j
        max,min = Three_maximin(h)
        j = max -min
        if j == h:
            print(f'黑洞数:{j}')
            break

x = int(input('输入数字:'))
max,min = Three_maximin(x)
print('max:{}\nmin:{}'.format(max,min))

Black_number(max,min)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-4-22 23:50

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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