鱼C论坛

 找回密码
 立即注册
查看: 5349|回复: 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 来实现,否则变量中存储的数将被改变。

假如这么写:
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 # 跳出循环
核心代码就是如此,我们来运行下:

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

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

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

评分

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

查看全部评分

本帖被以下淘专辑推荐:

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

使用道具 举报

发表于 2021-7-11 21:04:54 From FishC Mobile | 显示全部楼层
只会暴力
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-7-12 14:25:52 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-8-7 20:34:38 | 显示全部楼层
视频更新咯
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

这代码 没有灵魂哇!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-8 20:32:05 | 显示全部楼层
小甲鱼的新视频还没更新到函数呢,所以用列表写的,有点复杂呀!
n = int(input('请输入一个三位数:'))
a = n % 10
b = (n // 10) % 10
c = n // 100
rhyme = [a,b,c]
rhymemin =rhyme.copy()
rhymemin.sort()
rhymemax = rhyme.copy()
rhymemax.sort(reverse = True)
h = rhymemax[0]*100 + rhymemax[1]*10 + rhymemax[2]
l = rhymemin[0]*100 + rhymemin[1]*10 + rhymemin[2]
j = h - l
while h > l:
    m = j
    m1 = m % 10
    m2 = (m // 10) % 10
    m3 = m // 100
    me = [m1,m2,m3]
    memin = me.copy()
    memin.sort()
    memax = me.copy()
    memax.sort(reverse = True)
    mh = memax[0]*100 + memax[1]*10 + memax[2]
    ml = memin[0]*100 + memin[1]*10 + memin[2]
    j = mh - ml
    if j == m:
        print(f'黑洞数为{j}')
        break
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-5-8 22:29:11 | 显示全部楼层
keypoint:前后两次差值结果相同
想知道小甲鱼最近在做啥?请访问 -> 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)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-15 15:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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