谁考了第k名

GitHub跳转原题关系图返回列表

把每个学生存成(学号, 成绩)二元组,按成绩降序排序后取第 k 个;注意学号按字符串读入保留前导零,成绩用 %g 输出。

OJ: roj

题目 ID: 1176

难度:入门

标签:排序浮点数python数组

创建: 2026-09-29 22:15

更新: 2026-10-05 04:26

题目描述

考试中每个学生的成绩互不相同,已知每个学生的学号和成绩,求考第 kk 名学生的学号和成绩。 输入:第一行两个整数 nn(1⩽n⩽1001 \leqslant n \leqslant 100)和 kk(1⩽k⩽n1 \leqslant k \leqslant n);其后 nn 行,每行一个学号(整数)和一个成绩(浮点数),用空格分隔。 输出:第 kk 名学生的学号和成绩,中间用空格分隔,成绩请用 %g 输出。样例(期望输出 90788004 68.4):

text
5 3
90788001 67.8
90788002 90.3
90788003 61
90788004 68.4
90788005 73.9

思路

成绩降序排序后的第 kk 个学生就是答案:把(学号,成绩)放在一起按成绩从大到小排序后输出第 kk 个。两个易错点:学号可能带前导零(如 092),要用字符串原样读入输出;成绩必须按数值比较并按 %g 输出(68.4 不带尾零、61.0 输出成 61)。

参考代码

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-09-29 22:15
# update_at: 2026-10-04 10:21

import sys


def solve() -> None:
    data = iter(sys.stdin.buffer.read().split())
    n, k = int(next(data)), int(next(data))  # n、k 转成 int;学号留在 data 里保持 bytes,避免丢前导零
    # 第 i 个学生是 (学号, 成绩);成绩必须转成 float,字符串比较会把 "63.100" 排在 "63.2" 前面。
    students = [(sid, float(score)) for sid, score in zip(data, data)]
    # 成绩互不相同,故不存在并列,降序排序后第 k-1 个下标就是第 k 名。
    students.sort(key=lambda stu: stu[1], reverse=True)
    sid, score = students[k - 1]
    # 学号保持原始字节输出,保留测试数据里的前导零(如 092);成绩按 %g 输出小数(68.4,而非 68.400000)。
    print(f"{sid.decode()} {score:g}")


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-05 04:26
 * update_at: 2026-10-05 04:26
 */
#include <cstdio>
#include <algorithm>
using namespace std;

typedef long long ll;

const int MAXN = 105;

// 学号可能带前导零(如 092),用字符串原样读入、原样输出
struct Student {
    char id[20];
    double score;
};

Student stu[MAXN]; // stu[i] 表示第 i 个学生的(学号, 成绩)

int main() {
    int n, k;
    scanf("%d %d", &n, &k);
    for (int i = 1; i <= n; ++i)
        scanf("%s %lf", stu[i].id, &stu[i].score);

    // 成绩互不相同,按成绩从大到小排序,排好后第 k 个就是第 k 名
    for (int i = 1; i <= n; ++i)
        for (int j = i + 1; j <= n; ++j)
            if (stu[j].score > stu[i].score)
                swap(stu[i], stu[j]);

    // 成绩按 %g 输出:68.4 不带尾零,61.0 输出成 61
    printf("%s %g\n", stu[k].id, stu[k].score);
    return 0;
}