一、题目
题目描述
放暑假了,小明决定到某旅游景点游玩,他在网上搜索到了各种价位的酒店(长度为n的数组A),他的心理价位是x元,请帮他筛选出k个最接近x元的酒店(n>=k>0),并由低到高打印酒店的价格。
输入描述
第一行:n, k, x
第二行:A0 A1 A2...An-1
输出描述
从低到高打印筛选出的酒店价格
示例1
输入
10 5 6
1 2 3 4 5 6 7 8 9 10
1
2
输出
4 5 6 7 8
1
说明
示例2
输入
10 4 6
10 9 8 7 6 5 4 3 2 1
1
2
输出
4 5 6 7
1
说明
示例3
输入
6 3 1000
30 30 200 500 70 300
1
2
输出
200 300 500
1
说明
解题思路
输入解释
第一行包含三个整数 n、k 和 x:
n:酒店价格数组的长度,即有 n 个酒店。
k:需要选择的最接近心理价位 x 的酒店数量。
x:用户的心理价位。
第二行是酒店价格数组 A,其中 A0 到 An-1 代表不同酒店的价格。
示例说明
示例 1
输入:
10 5 6
1 2 3 4 5 6 7 8 9 10
1
2
解释:
用户心理价位是 6。
每个价格与 6 的差距分别是:5,4,3,2,1,0,1,2,3,4。
按差距排序后,最接近的 5 个价格为:4,5,6,7,8。
最终输出为:4 5 6 7 8。
示例 2
输入:
10 4 6
10 9 8 7 6 5 4 3 2 1
1
2
解释:
用户心理价位是 6。
每个价格与 6 的差距分别是:4,3,2,1,0,1,2,3,4,5。
按差距排序后,最接近的 4 个价格为:4,5,6,7。
最终输出为:4 5 6 7。
示例 3
输入:
6 3 1000
30 30 200 500 70 300
1
2
解释:
用户心理价位是 1000。
每个价格与 1000 的差距分别是:970,970,800,500,930,700。
按差距排序后,最接近的 3 个价格为:200,300,500。
最终输出为:200 300 500。
解题思路
优先选择价格最接近心理价位的酒店,若两家酒店和心理价位差价相同,则选择价格较低的酒店。(比如100元和300元距离心理价位200元同样接近,此时选择100元)
酒店价格可能相同重复
二、代码
python
n, k, x = map(int, input().split())
prices = list(map(int, input().split()))
sorted_prices = sorted(prices)
price_rating = sorted([(price, abs(price - x)) for price in sorted_prices], key=lambda item: item[1])
print(price_rating)
picked_price = sorted(item[0] for item in price_rating[:k])
print(picked_price)
print(' '.join(map(str, picked_price)))
说明:
这段代码中使用了三次 sorted() 函数:
-
第一次
sorted():sorted_prices = sorted(prices)- 作用:对原始价格列表进行升序排序
- 目的:确保后续处理时价格是有序的,便于处理相同差值时选择较低价格
-
第二次
sorted():price_rating = sorted([(price, abs(price - x)) for price in sorted_prices], key=lambda item: item[1])- 作用:按价格与心理价位
x的绝对差值进行排序 - 关键:使用
key=lambda item: item[1]指定按元组的第二个元素(差值)排序 - 效果:实现"最接近优先"的排序规则
- 作用:按价格与心理价位
-
第三次
sorted():picked_price = sorted(item[0] for item in price_rating[:k])- 作用:对选出的前k个最接近的价格进行升序排序
- 目的:满足题目要求"由低到高打印酒店的价格"
这三次 sorted() 调用分别完成了:原始数据排序、按接近程度排序、最终输出排序,共同实现了题目的完整逻辑。
三、sorted() 方法总结
在上面的代码中,我们使用了 Python 内置的 sorted() 函数来对列表进行排序。这里对 sorted() 方法进行一个详细的总结。
1. 基本语法
python
sorted(iterable, key=None, reverse=False)
- iterable: 需要排序的可迭代对象(如列表、元组、字符串等)。
- key: 可选参数,指定一个函数,该函数用于从每个元素中提取一个用于比较的键。
- reverse : 可选参数,布尔值。默认为
False表示升序排序,设为True则为降序排序。 - 返回值 : 返回一个新的已排序列表,不会修改原可迭代对象。
2. 与 list.sort() 的区别
sorted()返回一个新的排序后的列表,原列表不变。list.sort()是列表的方法,直接修改原列表,并返回None。
python
my_list = [3, 1, 2]
new_list = sorted(my_list) # my_list 不变,new_list 为 [1, 2, 3]
my_list.sort() # my_list 变为 [1, 2, 3]
3. key 参数详解
key 参数是 sorted() 最强大的功能之一,它允许我们自定义排序规则。
a) 按元素的某个属性排序
python
students = [('Alice', 88), ('Bob', 95), ('Charlie', 78)]
# 按分数排序
sorted_by_score = sorted(students, key=lambda s: s[1]) # [('Charlie', 78), ('Alice', 88), ('Bob', 95)]
b) 按多个条件排序
可以通过返回一个元组来实现多级排序。
python
# 先按分数降序,分数相同按名字升序
sorted_students = sorted(students, key=lambda s: (-s[1], s[0]))
c) 使用内置函数
python
words = ['apple', 'Banana', 'cherry', 'Date']
# 不区分大小写排序
sorted_words = sorted(words, key=str.lower) # ['apple', 'Banana', 'cherry', 'Date']
4. 在本题目中的应用
回顾我们题目中的代码:
python
price_rating = sorted([(price, abs(price - x)) for price in sorted_prices], key=lambda item: item[1])
这里我们创建了一个元组列表 (price, abs(price - x)),然后使用 sorted() 并指定 key=lambda item: item[1],即按照每个元组的第二个元素(价格与心理价位的绝对差值)进行排序。这样就实现了"最接近优先"的排序规则。
5. 性能与稳定性
sorted()使用的是 Timsort 算法,时间复杂度为 O(n log n)。- Timsort 是稳定的排序算法,这意味着当两个元素比较相等时,它们原有的相对顺序会被保留。这在多级排序中非常有用。
6. 对复杂数据结构排序
可以对字典、对象列表等进行排序。
python
# 对字典按键或值排序
my_dict = {'b': 2, 'a': 1, 'c': 3}
sorted_by_key = sorted(my_dict.items()) # [('a', 1), ('b', 2), ('c', 3)]
sorted_by_value = sorted(my_dict.items(), key=lambda x: x[1]) # [('a', 1), ('b', 2), ('c', 3)]
7. 总结表格
| 特性 | sorted() |
list.sort() |
|---|---|---|
| 适用对象 | 任何可迭代对象 | 仅列表 |
| 返回值 | 新的排序列表 | None |
| 是否修改原数据 | 否 | 是 |
| 排序稳定性 | 是 | 是 |
掌握 sorted() 方法及其 key 参数的灵活使用,是编写简洁高效 Python 代码的关键技能之一。