用元组保存学生成绩,枚举所有学生对并检查三科分差和总分分差。
OJ: luogu
题目 ID: P5741
难度:普及-
标签:模拟枚举结构体python
日期: 2026-07-15 21:15
题意
给出按字典序排列的学生信息。如果两个学生每一科分差都不超过 5,且总分分差不超过 10,就输出这对学生姓名。输出顺序也要按字典序组合顺序。
思路
输入姓名已经按字典序排列。因此只要按下标枚举 i < j 的学生对,输出顺序就满足题目要求。
把判断封装成函数:
python
is_close(left, right)它检查:
- 三科分差都不超过
5; - 总分分差不超过
10。
N <= 1000,枚举所有学生对是
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/brute_force_validation.md:for i in range(n)与for j in range(i+1, n)是枚举无序点对的常用写法。/home/rainboy/mycode/hugo-blog/content/program_language/python/collections_toolkit.md:元组可保存固定字段记录。abs(a - b)计算分差。- 把总分和判断逻辑封装成函数,可以让双重循环更清楚。
代码
python
def total(student):
return student[1] + student[2] + student[3]
def is_close(left, right):
for subject in range(1, 4):
if abs(left[subject] - right[subject]) > 5:
return False
return abs(total(left) - total(right)) <= 10
n = int(input())
students = []
for _ in range(n):
name, chinese, math, english = input().split()
students.append((name, int(chinese), int(math), int(english)))
for i in range(n):
for j in range(i + 1, n):
if is_close(students[i], students[j]):
print(students[i][0], students[j][0])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-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
struct Student {
char name[15];
int ch, ma, en, tot;
};
Student stu[1005];
int n;
// 判断两名学生是否为"旗鼓相当的对手"
bool is_close(Student &a, Student &b) {
if (abs(a.ch - b.ch) > 5) return false;
if (abs(a.ma - b.ma) > 5) return false;
if (abs(a.en - b.en) > 5) return false;
if (abs(a.tot - b.tot) > 10) return false;
return true;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> stu[i].name >> stu[i].ch >> stu[i].ma >> stu[i].en;
stu[i].tot = stu[i].ch + stu[i].ma + stu[i].en;
}
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
if (is_close(stu[i], stu[j]))
cout << stu[i].name << " " << stu[j].name << "\n";
}
}
return 0;
}复杂度
枚举所有学生对,时间复杂度是
总结
当输入顺序已经满足输出顺序时,不必额外排序。直接按 i < j 枚举学生对,既避免重复,也保证姓名顺序。