关于L2-009抢红包题目的Python实现,我将从问题分析、核心算法、代码实现和测试点解析四个方面进行详细说明。
## 问题分析
这是一个典型的排序和统计问题,需要处理以下核心要素:
| 需求点 | 具体描述 |
|--------|----------|
| 输入格式 | 第一行N表示发红包人数,随后N行每行K表示抢到红包人数,接着K对数据(编号, 金额) |
| 输出要求 | 按收入降序排序,收入相同按抢到红包数降序,仍相同按编号升序 |
| 金额精度 | 金额为浮点数,需要精确到小数点后2位 |
## 核心算法设计
### 数据结构选择
```python
# 使用字典存储每个人的红包统计信息
people = {
id: {
'income': 0.0, # 总收入
'count': 0, # 抢到红包数量
'id': id # 人员编号
}
for id in range(1, N+1)
}
```
### 排序策略
```python
def sort_people(people_dict):
"""自定义排序函数"""
sorted_list = sorted(people_dict.values(),
key=lambda x: (-x['income'], -x['count'], x['id']))
return sorted_list
```
## 完整代码实现
```python
def red_packet_solution():
# 读取输入数据
N = int(input().strip())
# 初始化人员字典
people = {}
for i in range(1, N + 1):
people[i] = {'income': 0.0, 'count': 0, 'id': i}
# 处理每个发红包者的记录
for i in range(1, N + 1):
data = list(map(int, input().split()))
K = data[0]
total_amount = 0
# 处理每个抢红包记录
for j in range(1, len(data), 2):
receiver_id = data[j]
amount = data[j + 1] / 100.0 # 分转元
# 更新接收者信息
people[receiver_id]['income'] += amount
people[receiver_id]['count'] += 1
total_amount += amount
# 更新发红包者的收入(负数表示支出)
people[i]['income'] -= total_amount
# 转换为列表并排序
result = list(people.values())
result.sort(key=lambda x: (-x['income'], -x['count'], x['id']))
# 输出结果
for person in result:
print(f"{person['id']} {person['income']:.2f} {person['count']}")
# 调用函数
if __name__ == "__main__":
red_packet_solution()
```
## 测试点分析与关键技巧
### 常见测试点及解决方案
| 测试点类型 | 潜在问题 | 解决方案 |
|------------|----------|----------|
| **边界测试** | N=1的极端情况 | 确保单人也正确处理收支 [ref_1] |
| **精度测试** | 浮点数精度误差 | 使用Decimal或乘以100转为整数计算 |
| **排序测试** | 多重排序规则 | 严格遵循收入→数量→编号的优先级 |
### 精度处理优化版本
```python
from decimal import Decimal, ROUND_HALF_UP
def precise_red_packet():
N = int(input().strip())
people = {}
for i in range(1, N + 1):
people[i] = {'income': Decimal('0'), 'count': 0, 'id': i}
for i in range(1, N + 1):
data = list(map(int, input().split()))
K = data[0]
total = Decimal('0')
for j in range(1, len(data), 2):
receiver_id = data[j]
amount = Decimal(str(data[j + 1])) / Decimal('100')
people[receiver_id]['income'] += amount
people[receiver_id]['count'] += 1
total += amount
people[i]['income'] -= total
result = sorted(people.values(),
key=lambda x: (-float(x['income']), -x['count'], x['id']))
for person in result:
income_float = float(person['income'])
print(f"{person['id']} {income_float:.2f} {person['count']}")
```
## 关键注意事项
1. **输入解析**:注意每行第一个数字K后面跟着K对数据,需要正确计算偏移量
2. **金额单位**:题目中金额以"分"为单位输入,输出需要转为"元"并保留两位小数
3. **发红包者**:发红包的人需要减去发出的总金额,这是容易忽略的关键点
4. **排序稳定性**:当主要排序条件相同时,要确保次要排序条件的正确应用
通过以上完整的分析和代码实现,应该能够通过所有的测试点。建议在提交前使用多种边界情况进行测试,特别是N=1、金额为0等特殊情况。