题目描述

小蓝对一个数的数位之和很感兴趣,今天他要按照数位之和给数排序。当两个数各个数位之和不同时,将数位和较小的排在前面,当数位之和相等时,将数值小的排在前面。

例如,2022 排在 409 前面,因为 2022 的数位之和是 6,小于 409 的数位之和 13。

又如,6 排在 2022 前面,因为它们的数位之和相同,而 6 小于 2022。

给定正整数 n,m,请问对 1 到 n 采用这种方法排序时,排在第 m 个的元素是多少?

输入格式

输入第一行包含一个正整数 n。

第二行包含一个正整数 m。

输出格式

输出一行包含一个整数,表示答案。

样例输入

13
5

样例输出

3

提示

1 到 13 的排序为:1, 10, 2, 11, 3, 12, 4, 13, 5, 6, 7, 8, 9。第 5 个数为 3。

对于 30% 的评测用例,1 ≤ m ≤ n ≤ 300。

对于 50% 的评测用例,1 ≤ m ≤ n ≤ 1000。

对于所有评测用例,1 ≤ m ≤ n ≤ 10^6。

代码演示:

n = int(input())
m = int(input())
list_1 = [str(i) for i in range(1, n + 1)] # 将n个数以字符串的形式存入列表
list_2 = sorted(list_1, key=lambda x: sum(map(int, x))) # 因为上面将数字转换为了字符串,所以代表数字的每位数都是一个字符
print(list_2[m - 1]) # 再利用sum函数求数位和,即可

解题思路:

本题的解题思路在于算出位数和,并将其排序

首先先了解一个小技巧,即一个str类型的数字字符串,将其用map函数转换为int类型的列表时,每一个单独的字符即数字为一个元素,如下列代码

m = '123456'
print(list(map(int,m)))

结果:

[1, 2, 3, 4, 5, 6]

了解完之后就可以着手代码的编写了

按照题目要求首先是输入数列的长度和所要找的数字的序号。

按照上述代码,我们可以将数列以str类型存入字符串,

当然我们也可以先以int类型存入列表,在map函数引用的时候再将其先转str再转int,如

n = int(input())
m = int(input())
list_1 = [i for i in range(1, n + 1)] # 将n个数以字符串的形式存入列表
list_2 = sorted(list_1, key=lambda x: sum(map(int, str(x)))) # 因为上面将数字转换为了字符串,所以代表数字的每位数都是一个字符
print(list_2[m - 1]) # 再利用sum函数求数位和,即可

下来就是排序的问题了,在这里用的是sorted函数

sorted(iterable, cmp=None, key=None, reverse=False)

参数说明:

  • iterable – 可迭代对象。
  • cmp – 比较的函数,这个具有两个参数,参数的值都是从可迭代对象中取出,此函数必须遵守的规则为,大于则返回1,小于则返回-1,等于则返回0。
  • key – 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
  • reverse – 排序规则,reverse = True 降序 , reverse = False 升序(默认)。

key是主要的,本题要求的是比较数位和的大小和从小到大排列的

数位和需要用到sum函数和map函数,map函数是找到数位,然后再用sum函数求和,sorted函数默认的是从小到大排列,那么数位和相同的也是按从小到大排的

lambda用法可参考以下文章:

http://t.csdn.cn/Pqm5V