按成绩降序、同分报名号升序排序后取第 ⌊1.5m⌋ 名的分数作分数线,再输出所有不低于分数线的选手。
OJ: roj
题目 ID: 3569
难度:普及-
标签:排序模拟python
创建: 2026-10-02 08:12
更新: 2026-10-07 13:50
题目描述
给定
数据范围:
思路
按
参考代码
Python 版:
python
#!/usr/bin/env python3
# Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
# rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
# rainboy的学习导航网站: https://idx.roj.ac.cn
# create_at: 2026-10-02 08:12
# update_at: 2026-10-02 08:12
import sys
def solve() -> None:
data = iter(map(int, sys.stdin.buffer.read().split()))
n, m = next(data), next(data)
# 读入 (报名号, 成绩) 对
people: list[tuple[int, int]] = [(next(data), next(data)) for _ in range(n)]
# 成绩降序、成绩相同报名号升序:排序键直接取 (-成绩, 报名号)
ranked: list[tuple[int, int]] = sorted(people, key=lambda p: (-p[1], p[0]))
# 面试分数线 = 排名 floor(m*150%) 的选手分数(ranked 下标从 0 起)
cutoff_rank = m * 3 // 2 - 1
line = ranked[cutoff_rank][1]
# 不低于分数线的全部进面试(含重分扩招)
admitted: list[tuple[int, int]] = [p for p in ranked if p[1] >= line]
out: list[str] = [f"{line} {len(admitted)}"]
out += (f"{k} {s}" for k, s in admitted)
sys.stdout.write("\n".join(out))
if __name__ == "__main__":
solve()C++ 版(同一算法):
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-10-06 14:15
* update_at: 2026-10-06 14:15
*/
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 5005;
struct Person {
int k; // 报名号
int s; // 成绩
} a[MAXN];
int n, m;
// 成绩降序,成绩相同则报名号升序
bool cmp(const Person &x, const Person &y) {
if (x.s != y.s) return x.s > y.s;
return x.k < y.k;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i].k >> a[i].s;
}
sort(a + 1, a + n + 1, cmp);
int r = m * 3 / 2; // 向下取整后的排名位置(1-indexed)
int line = a[r].s; // 面试分数线
// 统计不低于分数线的实际人数
int cnt = 0;
for (int i = 1; i <= n; ++i) {
if (a[i].s >= line) ++cnt;
}
cout << line << " " << cnt << "\n";
for (int i = 1; i <= n; ++i) {
if (a[i].s >= line) {
cout << a[i].k << " " << a[i].s << "\n";
}
}
return 0;
}