(python3) 1019. 数字黑洞 (20分)

题目是酱紫的:

给定任一个各位数字不完全相同的4位正整数,如果我们先把4个数字按非递增排序,再按非递减排序,然后用第1个数字减第2个数字,将得到一个新的数字。一直重复这样做,我们很快会停在有“数字黑洞”之称的6174,这个神奇的数字也叫Kaprekar常数。

例如,我们从6767开始,将得到

7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
7641 - 1467 = 6174
... ...

现给定任意4位正整数,请编写程序演示到达黑洞的过程。

输入格式:

输入给出一个(0, 10000)区间内的正整数N。

输出格式:

如果N的4位数字全相等,则在一行内输出“N - N = 0000”;否则将计算的每一步在一行内输出,直到6174作为差出现,输出格式见样例。注意每个数字按4位数格式输出。

输入样例1:
6767
输出样例1:
7766 - 6677 = 1089
9810 - 0189 = 9621
9621 - 1269 = 8352
8532 - 2358 = 6174
输入样例2:
2222
输出样例2:
2222 - 2222 = 0000
题目解析:

题目不难理解,但是存在许多陷阱会使你各种测试点过不去,先看代码理清思路再讲解陷阱:


str_ = input()
ret = "{0:0>4}".format(str_)     # 0 填充的4位字符串

if len(set(ret))== 1 :            # 4位数均相同的情况
    print("%s - %s = 0000" %(ret,ret))
else:
    while  True:                           # 循环处理ret字符串,先变成数字的列表,再排序、拼接、相减
        num_lt = list(map(int, ret))
        num1 = sorted(num_lt,reverse=1)
        num2 = sorted(num_lt)
        str1 = "".join(list(map(str,num1)))
        str2 = "".join(list(map(str,num2)))
        ret = "{0:0>4}".format(int(str1)-int(str2))         # 得到新的ret字符串
        print("{0:0>4} - {1:0>4} = {2}".format(str1,str2,ret))      # 输出这一次处理的结果
        if ret == '6174' :                   # 退出条件判断
            break

深刻总结:

1.主要思路:一个数,确保填充为四位,各个数字升序降序排列得到两个新数(是核心部位却最不重要),相减直到得到6174.

2.主要陷阱1:输入数字在(0,1000)即1000以内,或者计算过程中出现999这个三位数(如1000-1;9998-8999等),需要字符串格式化填充0.

前者举例,若输入666,不进行格式化会导致set('666')长度为1 而错分到第一种情况;后者会导致出现999后得到999-999=0000然后进入死循环。

因此输入str_后立刻填充得到ret(这是该题最重要的一个变量),然后分情况处理;

当输入的数字在1000以内时,开篇处的ret格式化更是起了大作用,可以衔接主要代码部分,如输入666,num_lt=[0,6,6,6],也简化了过程;

两数相减得到新的ret后也是直接格式化,以便于输出及衔接下一步循环。

3.主要陷阱2:完成上面后发现仍然有一测试点过不去,当时循环条件是酱紫的 while ret != '6174'.仔细读题发现另一小陷阱。“直到6174作为差出现”,也就是那个测试点应该是6174,当输入6174时要进行一次循环得到差才可,因此改为如上代码的退出条件。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值