- 1.问题描述
- 2.问题分析
- 3.算法设计
- 4.比较三个数的大小并将其重组
- 5.寻找“黑洞数”
- 6.完整的程序
1.问题描述
编程求三位数中的“黑洞数”。
黑洞数又称陷阱数,是指任何一个数字不全相同的整数,在经过有限次“重排求差”操作后,总会得到某一个或一些数,这些数即为黑洞数。“重排求差”操作是将组成一个数的各位数字重排,将得到的最大数减去最小数。例如,207的“重排求差”操作序列是:720-027=693,963-369=594,954-459=495,此时再进行“重排求差”操作不会发生改变。再用208计算一次,也是停止到495,所以495是三位黑洞数。
2.问题分析
根据“黑洞数”定义,对于任意一个数字不全相同的整数,最后结果总会掉入到一个黑洞圈或黑洞数里,最后结果一旦为黑洞数,无论再重复进行多少次的“重排求差”操作,结果都是一样的,因此可把结果相等作为判断“黑洞数”的依据。
3.算法设计
过程如下:
1)将任意一个三位数进行拆分。
2)拆分后的数据重新组合,将可以组合的最大值减去最小值,差值赋给变量j。
3)将当前差值暂存到另一变量h中:h=j。
4)对变量j执行拆分、重组、求差操作,差值仍然存储到变量j中。
5)判断当前差值j是否与前一次的差值h相等,若相等,则将差值输出并结束循环,否则重复步骤3~5。
4.比较三个数的大小并将其重组
求“黑洞数”的关键是求出拆分后所能组成的最大值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),功能分别是求由三个数组成的最大值和最小值。代码如下:
# 求三位数的组合最大值
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)中需返回的是最小值c100+b10+a。
5.寻找“黑洞数”
将第一次得到的差值j赋给变量h,因在后面的编程过程中会再次将得到的差值赋给变量j,为避免j中存储的原值找不到,故先把前一次的差值暂存到另一个变量h中。在比较过程中一旦两次结果相等,循环过程即可结束,可用break语句实现。判定条件j==h可以在循环体中用if语句实现,也可写在while语句中。寻找“黑洞数”的方法代码如下:
# 求黑洞数
def black_number(max, min):
j = max - min
k = 0
while k < min: # k控制循环次数
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("%d " % j)
break # 跳出循环
k += 1
6.完整的程序
完整的程序如下:
%%time
# 黑洞数
# 求三位数的组合最大值
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
#求三位数的组合最小值
def three_min(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 c*100 + b*10 + a
# 求黑洞数
def black_number(max, min):
j = max - min
k = 0
while k < min: # k控制循环次数
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("%d " % j)
break # 跳出循环
k += 1
if __name__ == "__main__":
i = int(input("请输入一个三位整数:"))
print(f'输入的数字为:{i}')
hun = i // 100 # 百位
ten = i % 100 // 10 # 十位
bit = i % 10 # 个位
max = three_max(hun, ten, bit) # 最大值
min = three_min(hun, ten, bit) # 最小值
print("max = ", max)
print("min = ", min)
black_number(max, min)
输入的数字为:108
max = 810
min = 18
495
CPU times: user 21.2 ms, sys: 10 ms, total: 31.2 ms
Wall time: 2.94 s