1 条题解
-
0
📝 题目大意
有 名考生,每人有数学成绩 和英语成绩 。分三轮依次录取:先按数学成绩从高到低录 人,再从未录取者中按英语成绩从高到低录 人,最后从未录取者中按总分从高到低录 人。同分时编号小的优先。输出所有录取者编号(升序)。
💡 解题思路
-
题目分析:,数据规模很小,直接模拟三轮排序筛选即可。关键约束是 ,保证录取人数合法,且每轮筛选必须跳过已录取的考生。
-
算法推导:
- 将学生信息(编号、数学、英语、总分)存入结构体数组
stu。 - 用一个
order数组存储学生下标( 到 ),排序order而非直接排stu,避免整体拷贝结构体。 - 第一轮:按数学降序排序
order,同分按编号升序。遍历order,将未录取的前 人标记为passed并加入qualified。 - 第二轮:按英语降序重新排序
order,同分按编号升序。同样跳过已录取者,取前 人。 - 第三轮:按总分降序重新排序
order,同分按编号升序。跳过已录取者,取前 人。 - 最后将
qualified升序排序后输出。
- 将学生信息(编号、数学、英语、总分)存入结构体数组
-
边界与细节:
- 可能为 (如样例 1 中 ),此时对应轮次不录取任何人,
cnt < 0条件直接跳过循环。 - 每轮遍历时需同时检查
i < N和cnt < 目标人数,防止越界或超出名额。 - 排序比较器必须同时保证主关键字降序和次关键字(编号)升序,否则同分时选择错误。
- 可能为 (如样例 1 中 ),此时对应轮次不录取任何人,
⏱️ 复杂度分析
- 时间复杂度:,三轮排序各 ,最后输出排序 , 完全可行。
- 空间复杂度:,存储学生信息和辅助数组。
💻 标准代码 (C++)
#include<bits/stdc++.h> using namespace std; // 学生结构体:编号、数学成绩、英语成绩、总分 struct Student { int id; int math; int eng; int total; }; int main(){ int N, X, Y, Z; cin >> N >> X >> Y >> Z; vector<Student> stu(N); // 读入编号和数学成绩 for(int i = 0; i < N; i++) { stu[i].id = i + 1; cin >> stu[i].math; } // 读入英语成绩并计算总分 for(int i = 0; i < N; i++) { cin >> stu[i].eng; stu[i].total = stu[i].math + stu[i].eng; } vector<bool> passed(N, false); // 标记是否已被录取 vector<int> qualified; // 录取者编号列表 vector<int> order(N); // 排序用的下标数组 for(int i = 0; i < N; i++) order[i] = i; // 第一轮:按数学成绩降序选 X 人,同分按编号升序 sort(order.begin(), order.end(), [&](int i, int j){ if(stu[i].math != stu[j].math) return stu[i].math > stu[j].math; return stu[i].id < stu[j].id; }); int cnt = 0; for(int i = 0; i < N && cnt < X; i++) { int idx = order[i]; if(!passed[idx]){ passed[idx] = true; qualified.push_back(stu[idx].id); cnt++; } } // 第二轮:按英语成绩降序选 Y 人,同分按编号升序 sort(order.begin(), order.end(), [&](int i, int j){ if(stu[i].eng != stu[j].eng) return stu[i].eng > stu[j].eng; return stu[i].id < stu[j].id; }); cnt = 0; for(int i = 0; i < N && cnt < Y; i++) { int idx = order[i]; if(!passed[idx]){ passed[idx] = true; qualified.push_back(stu[idx].id); cnt++; } } // 第三轮:按总分降序选 Z 人,同分按编号升序 sort(order.begin(), order.end(), [&](int i, int j){ if(stu[i].total != stu[j].total) return stu[i].total > stu[j].total; return stu[i].id < stu[j].id; }); cnt = 0; for(int i = 0; i < N && cnt < Z; i++){ int idx = order[i]; if(!passed[idx]){ passed[idx] = true; qualified.push_back(stu[idx].id); cnt++; } } // 按编号升序输出所有录取者 sort(qualified.begin(), qualified.end()); for(int id : qualified){ cout << id << endl; } return 0; } -
- 1
信息
- ID
- 621
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 1
- 上传者