鱼C-小师妹 发表于 2021-7-11 20:15:49

14 - 数之吟唱:黑洞数

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

https://www.bilibili.com/video/BV1HT4y1K7DY?p=16

https://xxx.ilovefishc.com/forum/202105/31/204333obvdca8ankppcn9v.png.thumb.jpg

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

任何一个数字不全相同的整数,在经过有限次“重排求差”操作后,总会得到某一个或一些数,这些数即为黑洞数。
“重排求差”操作是将组成一个数的各位数字重排,将得到的最大数减去最小数。

例如,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 来实现,否则变量中存储的数将被改变。

假如这么写:

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

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

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

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

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

代码如下:

def three_max(a, b, c):
    # a、b、c分别对应百位、十位、个位
    if a < b:
      # 如果a<b,则将变量a、b的值互换
      t = a
      a = b
      b = t
    if a < c:
      t = a
      a = c
      c = t
    if b < c:
      t = b
      b = c
      c = t
    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 就可以自定义函数,在需要的地方调用就好。

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

def black_number(max, min):
    j = max - min
    while min < max:   
      h = j# h记录上一次最大值与最小值的差
      hun = j // 100    # 百位
      ten = j % 100 // 10# 十位
      bit = j % 10# 个位
      max = three_max(hun, ten, bit)      # 最大值
      min = three_min(hun, ten, bit)      # 最小值
      j = max - min
      if j == h:# 最后两次差相等时,差即为所求黑洞数
            print("黑洞数=",j)
            break # 跳出循环
核心代码就是如此,我们来运行下:



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

源码:

wp231957 发表于 2021-7-11 21:04:54

只会暴力

hornwong 发表于 2021-7-12 14:25:52

{:5_95:}

鱼C-小师妹 发表于 2021-8-7 20:34:38

视频更新咯

Ediwin 发表于 2021-8-22 18:50:54

鱼C-小师妹 发表于 2021-8-7 20:34
视频更新咯

这代码 没有灵魂哇!

游刃鱿鱼 发表于 2021-11-8 20:32:05

小甲鱼的新视频还没更新到函数呢,所以用列表写的,有点复杂呀!
n = int(input('请输入一个三位数:'))
a = n % 10
b = (n // 10) % 10
c = n // 100
rhyme =
rhymemin =rhyme.copy()
rhymemin.sort()
rhymemax = rhyme.copy()
rhymemax.sort(reverse = True)
h = rhymemax*100 + rhymemax*10 + rhymemax
l = rhymemin*100 + rhymemin*10 + rhymemin
j = h - l
while h > l:
    m = j
    m1 = m % 10
    m2 = (m // 10) % 10
    m3 = m // 100
    me =
    memin = me.copy()
    memin.sort()
    memax = me.copy()
    memax.sort(reverse = True)
    mh = memax*100 + memax*10 + memax
    ml = memin*100 + memin*10 + memin
    j = mh - ml
    if j == m:
      print(f'黑洞数为{j}')
      break

Hyjxsssss 发表于 2022-5-8 22:29:11

keypoint:前后两次差值结果相同

语与余 发表于 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)
页: [1]
查看完整版本: 14 - 数之吟唱:黑洞数