预订酒店问题

一、题目

题目描述

放暑假了,小明决定到某旅游景点游玩,他在网上搜索到了各种价位的酒店(长度为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() 函数:

  1. 第一次 sorted()sorted_prices = sorted(prices)

    • 作用:对原始价格列表进行升序排序
    • 目的:确保后续处理时价格是有序的,便于处理相同差值时选择较低价格
  2. 第二次 sorted()price_rating = sorted([(price, abs(price - x)) for price in sorted_prices], key=lambda item: item[1])

    • 作用:按价格与心理价位 x 的绝对差值进行排序
    • 关键:使用 key=lambda item: item[1] 指定按元组的第二个元素(差值)排序
    • 效果:实现"最接近优先"的排序规则
  3. 第三次 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 代码的关键技能之一。

相关推荐
No8g攻城狮1 小时前
【算法】什么是 DFS 与 BFS 及他们的区别
算法·深度优先·宽度优先
zww89491111 小时前
家政派单系统实战指南:从需求分析到智能调度算法落地
算法·需求分析
手写码匠1 小时前
华为云Flexus+DeepSeek征文|Dify 多 Agent 评测实战:用 DeepSeek-R1 当裁判,打造多智能体系统的自动化质量保障体系
人工智能·深度学习·算法·aigc
ZC跨境爬虫2 小时前
LeetCode 88. 合并两个有序数组(双指针详解 + Java Python 实现)
java·python·算法·leetcode
Nil2082 小时前
leetcode 238除了自身以外数组的乘积
数据结构·算法·leetcode
土司大王2 小时前
LeetCode hot100——最长连续序列
数据结构·算法·leetcode
caimouse2 小时前
ReactOS 图形系统分析(17):区域填充 — EngPaint / IntEngPaint(paint.c)
c语言·开发语言·算法
生态学者2 小时前
Ecological Indicators | 机场鸟调的新方法:用 AWM-PC1 读懂干扰梯度下的鸟类群落
人工智能·算法·r语言·微信公众平台
Herbert_hwt2 小时前
第六章 Java深入理解接口、函数式接口与lambda表达式
java·开发语言·算法