蓝桥杯第十三届题解——数位排序

#蓝桥杯 #python #map函数 #自定义排序

题目详情

问题描述

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

例如, 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,91,10,2,11,3,12,4,13,5,6,7,8,9 。第 5 个数为 3 。

评测用例规模与约定

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

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

对于所有评测用例, 1≤m≤n≤1061≤m≤n≤106 。

运行限制

  • 最大运行时间:3s
  • 最大运行内存: 512M

题解代码与分析

代码

# 计算数位和
def disum(num):
  return sum(map(int, str(num)))
  
n, m = int(input()), int(input())
  
ran = list(range(1, n + 1))

# 自定义排序获得想要的结果
ran.sort(key = lambda x : (disum(x), x))

print(ran[m - 1])

分析

由于python的排序用的是归并排序,时间复杂度是nlogn的,并且最大数据范围是1e6
,所以3秒的时间内使用sort排序直接暴力获取即可。

相关知识点

  1. Python内置map函数
  2. Python自定义排序

map函数

概念和具体语法

可以直接看例子,可以更快理解

map()函数是Python内置函数之一,主要用于对可迭代对象(如列表、元组等)中的每个元素应用一个指定的函数,然后返回一个结果迭代器。map()函数的基本语法为:

map(function, iterable1, iterable2, ...)

其中,function是一个函数,iterable1, iterable2, ...是一个或多个可迭代对象。map()函数将function应用于每个可迭代对象中对应位置的元素,返回一个新的迭代器,其中包含了经过function处理后的结果。

常见用法总结如下:

  1. 将一个函数应用于一个序列的每个元素,返回处理后的结果序列:

    numbers = [1, 2, 3, 4, 5]
    squared_numbers = map(lambda x: x**2, numbers)
    print(list(squared_numbers))  # 输出:[1, 4, 9, 16, 25]
    
  2. 可以同时传入多个序列,function应该接受相同数量的参数,对应位置的元素会被传入函数进行处理:

    numbers1 = [1, 2, 3]
    numbers2 = [4, 5, 6]
    summed_numbers = map(lambda x, y: x + y, numbers1, numbers2)
    print(list(summed_numbers))  # 输出:[5, 7, 9]
    
  3. 如果传入的可迭代对象长度不一致,map()函数会以最短的对象为准,超出部分会被忽略:

    numbers1 = [1, 2, 3]
    numbers2 = [4, 5]
    summed_numbers = map(lambda x, y: x + y, numbers1, numbers2)
    print(list(summed_numbers))  # 输出:[5, 7]
    
  4. 可以传入多个可迭代对象,但function函数只能接受一个参数,这样map()函数会将每个可迭代对象的对应位置的元素作为参数传入function

    numbers1 = [1, 2, 3]
    numbers2 = [4, 5, 6]
    summed_numbers = map(lambda x: x[0] + x[1], zip(numbers1, numbers2))
    print(list(summed_numbers))  # 输出:[5, 7, 9]
    

map()函数的返回值是一个迭代器,因此需要通过list()等函数将其转换为列表或其他类型的序列进行使用。

举个例子

以下是一个简单的例子,演示了如何使用map()函数将列表中的每个元素转换为字符串:

numbers = [1, 2, 3, 4, 5]
# 使用map()函数将每个元素转换为字符串
str_numbers = map(str, numbers)
# 将结果转换为列表并打印输出
print(list(str_numbers))  # 输出:['1', '2', '3', '4', '5']

在这个例子中,map(str, numbers)将列表numbers中的每个元素都应用了str()函数,将其转换为字符串。最后通过list()函数将结果转换为列表并打印输出。

自定义排序

可以直接看例子,可以更快理解

具体概念和语法

在Python中,可以通过自定义排序函数或使用lambda表达式来实现自定义排序。主要有两种方法:

  1. 使用sorted()函数和sort()方法的key参数:可以传入一个函数作为key参数,该函数接受一个元素并返回一个用于排序的关键值。

    numbers = [5, 2, 8, 1, 3]
    sorted_numbers = sorted(numbers, key=lambda x: x % 3)  # 按照元素对3取余的结果排序
    print(sorted_numbers)  # 输出:[3, 2, 5, 8, 1]
    
  2. 使用sorted()函数和sort()方法的cmp参数(Python 2中):可以传入一个比较函数作为cmp参数,该函数接受两个元素并返回负数、零或正数,表示第一个元素小于、等于或大于第二个元素。

    numbers = [5, 2, 8, 1, 3]
    sorted_numbers = sorted(numbers, cmp=lambda x, y: x % 3 - y % 3)  # 按照元素对3取余的结果排序
    print(sorted_numbers)  # 输出:[3, 2, 5, 8, 1]
    
  3. 使用functools.cmp_to_key()函数(Python 3.2+):将一个比较函数转换为一个键函数,以便用于sorted()函数和sort()方法的key参数。

    from functools import cmp_to_key
    
    numbers = [5, 2, 8, 1, 3]
    sorted_numbers = sorted(numbers, key=cmp_to_key(lambda x, y: x % 3 - y % 3))  # 按照元素对3取余的结果排序
    print(sorted_numbers)  # 输出:[3, 2, 5, 8, 1]
    

以上是几种常见的自定义排序方法,可以根据具体需求选择合适的方法。

举个例子

以下是一个例子,演示了如何使用自定义排序函数对元组列表进行排序。这个例子按照元组中第二个元素的值进行排序,如果第二个元素相同,则按照第一个元素的值进行排序:

# 定义一个元组列表
data = [(1, 3), (2, 2), (3, 1), (4, 3), (5, 2)]

# 定义一个自定义排序函数
def custom_sort(x):
    return x[1], x[0]

# 使用自定义排序函数进行排序
sorted_data = sorted(data, key=custom_sort)

# 输出排序结果
print(sorted_data)

在这个例子中,custom_sort函数定义了排序的规则,即先按照元组中第二个元素的值进行排序,如果第二个元素相同,则按照第一个元素的值进行排序。然后使用sorted()函数对元组列表进行排序,传入key=custom_sort参数来指定排序规则。最后打印排序后的结果。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值