
题目思路解析
这道彩票摇奖题目要求我们根据中奖号码判断多张彩票的中奖等级。核心在于高效计算彩票号码与中奖号码的交集大小,并根据交集大小确定中奖等级。
核心思考路径
- 数据读取:读取中奖号码和所有彩票号码
- 交集计算:对每张彩票计算与中奖号码的匹配个数
- 等级判定:根据匹配个数确定中奖等级
- 结果统计:统计各等级的中奖张数
关键考核知识点
1. 集合运算应用(⭐⭐⭐⭐⭐)
- 交集计算:快速判断号码是否存在
- 哈希集合:使用unordered_set实现O(1)查找
- 批量匹配:同时处理多个号码的匹配
2. 计数与统计(⭐⭐⭐)
- 等级映射:匹配个数到中奖等级的转换
- 结果累计:统计各等级的中奖数量
- 输出格式化:按要求格式输出结果
3. 输入输出处理(⭐⭐)
- 多行数据读取:处理不定数量的彩票数据
- 数据验证:确保号码在合法范围内
- 输出顺序:按特等奖到六等奖的顺序输出
C++完整实现
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
int main() {
int n;
cin >> n;
// 读取中奖号码
unordered_set<int> winning_numbers;
for (int i = 0; i < 7; ++i) {
int num;
cin >> num;
winning_numbers.insert(num);
}
// 初始化中奖等级计数器
vector<int> prize_count(7, 0); // 索引0:特等奖, 1:一等奖, ..., 6:六等奖
// 处理每张彩票
for (int i = 0; i < n; ++i) {
int match_count = 0;
// 读取彩票号码并计算匹配个数
for (int j = 0; j < 7; ++j) {
int num;
cin >> num;
if (winning_numbers.find(num) != winning_numbers.end()) {
match_count++;
}
}
// 根据匹配个数确定中奖等级
if (match_count >= 1 && match_count <= 7) {
prize_count[7 - match_count]++;
}
}
// 输出结果
for (int i = 0; i < 7; ++i) {
cout << prize_count[i];
if (i < 6) cout << " "; // 可选:添加空格分隔
}
cout << endl;
return 0;
}
代码解析与优化
1. 数据结构选择优化
// 使用unordered_set提高查找效率
unordered_set<int> winning_numbers;
// 替代方案:使用数组标记(当号码范围较小时)
bool number_exists[34] = {false};
2. 匹配计数优化
// 使用位运算或预计算优化
// 如果号码范围小,可以用位图表示
3. 复杂度分析
| 操作 | 时间复杂度 | 空间复杂度 | 说明 |
|---|---|---|---|
| 读取中奖号码 | O(7) | O(7) | 常数时间 |
| 处理单张彩票 | O(7) | O(1) | 每张彩票7次查找 |
| 总体复杂度 | O(7n) | O(7) | 线性复杂度 |
测试用例分析
| 测试案例 | 输入 | 预期输出 | 验证要点 |
|---|---|---|---|
| 样例1 | 2 23 31 11 14 19 17 18 12 8 9 23 1 16 7 11 7 10 21 2 31 | 0 0 0 0 0 1 1 | 基本功能 |
| 边界1 | 1 1 2 3 4 5 6 7 1 2 3 4 5 6 7 | 1 0 0 0 0 0 0 | 特等奖情况 |
| 边界2 | 1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 0 0 0 0 0 0 0 | 未中奖情况 |
| 特殊1 | 3 1 2 3 4 5 6 7 1 2 3 8 9 10 11 1 8 9 10 11 12 13 8 9 10 11 12 13 14 | 0 0 1 0 1 0 1 | 多等级中奖 |
常见错误与修正
错误1:等级映射错误
// 错误:直接使用匹配个数作为索引
prize_count[match_count]++; // 特等奖应该是7,但索引7越界
修正:
prize_count[7 - match_count]++; // 特等奖对应索引0
错误2:集合查找错误
// 错误:错误的使用find方法
if (winning_numbers.find(num)) // 应该检查是否等于end()
修正:
if (winning_numbers.find(num) != winning_numbers.end())
错误3:输出格式错误
// 错误:输出顺序错误
for (int i = 0; i < 7; i++) {
cout << prize_count[i] << endl; // 应该在一行输出
}
修正:
for (int i = 0; i < 7; i++) {
cout << prize_count[i];
}
cout << endl;
竞赛技巧总结
- 数据结构选择:根据数据特性选择合适的数据结构
- 算法优化:利用哈希集合实现快速查找
- 边界测试:测试全中、全不中等边界情况
- 代码简洁:保持逻辑清晰,避免复杂嵌套
拓展思考
1. 性能优化进阶
// 使用bitset优化空间(当号码范围固定时)
bitset<34> winning_numbers; // 33个号码+1个索引偏移
2. 功能扩展
// 支持多组中奖号码
vector<unordered_set<int>> multi_winning_numbers;
// 计算最佳中奖等级
3. 错误处理增强
// 添加输入验证
bool validateNumber(int num) {
return num >= 1 && num <= 33;
}
"彩票摇奖问题展示了如何将现实世界的规则转化为高效的算法实现,是集合运算在实际应用中的典型例子。"
实际应用价值:
- 彩票系统开发
- 抽奖活动程序设计
- 模式匹配算法实践
通过这道题目,我们不仅学会了算法实现技巧,更理解了如何将业务规则转化为可执行的代码逻辑。
&spm=1001.2101.3001.5002&articleId=152652257&d=1&t=3&u=68610bd86d58462eaf835660a9b0f69a)
963

被折叠的 条评论
为什么被折叠?



