1 条题解
-
0
题目解析
问题分析
这是一个根据特定规则选拔决赛选手的模拟题。我们需要从按成绩排好序的选手中,按照给定的资格规则选出20名决赛选手。
关键规则理解
- 选拔顺序:按成绩从高到低依次考虑
- 资格要求:选手必须满足以下条件之一
- 波兰国籍
- 在波兰居住
- 在波兰学习/工作
- (在输入中用
TAK表示满足资格且愿意参加)
- 选拔规则:
- 前10名:所有满足资格的选手中排名前10的
- 后10名:从剩余满足资格的选手中,排除曾参加决赛≥2次的选手,再选前10名
算法思路
核心思想:顺序扫描 + 条件筛选
代码采用了一种简洁高效的单次扫描方法:
- 按排名顺序处理:从第1名到最后1名依次考虑
- 两阶段合一:在扫描过程中同时完成前10名和后10名的选拔
- 条件判断:
- 前10名:只要满足资格 (
TAK) 就入选 - 后10名:除了满足资格,还要求决赛次数
< 2
- 前10名:只要满足资格 (
实现细节
if (s == "TAK" && ans.size() < 20) { if (ans.size() < 10 || x < 2) { ans.push_back(i + 1); } }ans.size() < 10:前10名阶段,不限制决赛次数x < 2:后10名阶段,要求决赛次数小于2次ans.size() < 20:总共只选20人
正确性证明
该算法的正确性基于:
- 排序保证:输入已按成绩从高到低排序,保证了选拔的公平性
- 阶段连续性:前10名选拔完后自动进入后10名选拔
- 条件满足:
- 前10名:所有
TAK选手,无论决赛次数 - 后10名:
TAK选手且决赛次数<2
- 前10名:所有
- 数量保证:题目保证能选出20人
复杂度分析
- 时间复杂度: - 只需一次线性扫描
- 空间复杂度: - 除了存储结果,只使用常数额外空间
- 最优性:每个选手只被处理一次,无法更优
算法特点
- 简洁高效:用最少的代码完成复杂规则的处理
- 逻辑清晰:通过条件判断自然地区分两个选拔阶段
- 边界处理:自动处理各种边界情况
- 竞赛友好:适合编程竞赛中对效率和正确性的要求
样例验证
以题目样例为例:
- 前10名:3,4,5,6,9,10,12,13,14,16(所有
TAK选手) - 后10名:从剩余
TAK选手中排除20,21,31(决赛次数≥2),得到18,22,23,24,25,26,27,28,30,32
这种方法巧妙地将两阶段选拔合并到一个循环中,体现了算法设计中的简洁美。
- 1
信息
- ID
- 4612
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者