题目链接
题目描述
你需要管理一个学生成绩系统,支持以下三种操作:
- 插入:
1 x y z
,登记一个新学生的成绩(语文x
,数学y
,外语z
)。 - 查询:
2
,输出当前系统中"成绩最好"的学生的各项成绩。 - 删除:
3
,删除当前系统中"成绩最好"的学生的记录。
这是一个主函数模式的题目,你需要自己处理输入和输出。
"成绩最好"的判定规则按以下优先级顺序比较:
- 总成绩高者优先。
- 若总成绩相同,则语文成绩高者优先。
- 若总成绩和语文成绩都相同,则数学成绩高者优先。
- 若以上三项都相同,则外语成绩高者优先。
- 如果所有成绩都相同,可以认为是并列的,删除时只删除一个。
示例: 输入:
10
1 93 27 6
2
3
1 31 46 2
1 100 85 84
2
2
1 2 40 3
2
2
输出:
93 27 6
100 85 84
100 85 84
100 85 84
100 85 84
解题思路
这个问题需要我们动态地找到并移除集合中的"最大值",这里的"最大值"由一个多层级的复杂规则定义。这正是**优先队列(最大堆)**的用武之地。
与上一题不同的是,我们现在要比较的不是单个整数,而是一个包含多项成绩的学生对象。因此,核心任务是教会优先队列如何根据我们的规则来比较两个学生对象。
自定义比较逻辑
- C++: 填充题目模板提供的
operator<
自由函数。要让std::priority_queue
(默认最大堆)正常工作,a < b
必须定义为 "a 的优先级是否低于 b"。然后,在insertValue
,deleteValue
,getTop
函数中分别实现对全局优先队列的push
,pop
,top
操作。 - Java: 填充
PriorityQueue
构造函数中匿名Comparator
的compare
方法。因为 Java 的PriorityQueue
默认是最小堆,我们需要让compare(a, b)
在a
优于b
时返回一个负数,从而模拟最大堆的行为。然后,在insertValue
,deleteValue
,getTop
函数中分别实现对全局优先队列的add
,poll
,peek
操作。 - Python:
heapq
模块实现的是最小堆。我们通过在Student
类中实现__lt__
(less than) 方法来定义比较规则。为了让成绩最好的学生被认为是"最小"的元素而浮到堆顶,self < other
的逻辑必须定义为 "self 的成绩是否优于 other"。然后,在insertValue
,deleteValue
,getTop
函数中分别调用heapq.heappush
,heapq.heappop
和访问s[0]
。
算法步骤:
- 根据模板要求,在指定位置(
operator<
,Comparator
, 或__lt__
)实现多级比较逻辑。 - 在
insert
,delete
,get
函数中封装对全局优先队列的相应操作。 - 主函数会调用这些封装好的函数来完成整个流程。
代码
#include<bits/stdc++.h>
using namespace std;
struct node{
int chinese, math, english, sum;
};
bool operator<(node a, node b){
if (a.sum != b.sum) return a.sum < b.sum;
if (a.chinese != b.chinese) return a.chinese < b.chinese;
if (a.math != b.math) return a.math < b.math;
return a.english < b.english;
}
priority_queue<node> s;
void insertValue(int chinese, int math, int english){
s.push({chinese, math, english, chinese + math + english});
}
void deleteValue(){
if (!s.empty()) {
s.pop();
}
}
node getTop(){
if (!s.empty()) {
return s.top();
}
return {}; // Should not be reached given problem constraints
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int q,op;
int x, y, z;
cin>>q;
while(q--){
cin>>op;
if(op==1){
cin>>x>>y>>z;
insertValue(x, y, z);
}
if(op==2){
node tmp = getTop();
cout<<tmp.chinese<<" "<<tmp.math<<" "<<tmp.english<<endl;
}
if(op==3){
deleteValue();
}
}
return 0;
}
import java.util.*;
class Student {
int chinese, math, english, sum;
public Student(int chinese, int math, int english) {
this.chinese = chinese;
this.math = math;
this.english = english;
this.sum = chinese + math + english;
}
}
public class Main {
// 使用Java的PriorityQueue实现成绩排序
static PriorityQueue<Student> s = new PriorityQueue<>(new Comparator<Student>() {
@Override
public int compare(Student a, Student b) {
// 返回负数表示 a 的优先级更高
if (a.sum != b.sum) return b.sum - a.sum;
if (a.chinese != b.chinese) return b.chinese - a.chinese;
if (a.math != b.math) return b.math - a.math;
return b.english - a.english;
}
});
public static void insertValue(int chinese, int math, int english) {
s.add(new Student(chinese, math, english));
}
public static void deleteValue() {
if (!s.isEmpty()) {
s.poll();
}
}
public static Student getTop() {
if (!s.isEmpty()) {
return s.peek();
}
return null;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int q = scanner.nextInt();
while (q-- > 0) {
int op = scanner.nextInt();
if (op == 1) {
int chinese = scanner.nextInt();
int math = scanner.nextInt();
int english = scanner.nextInt();
insertValue(chinese, math, english);
}
if (op == 2) {
Student top = getTop();
if (top != null) {
System.out.println(top.chinese + " " + top.math + " " + top.english);
}
}
if (op == 3) {
deleteValue();
}
}
scanner.close();
}
}
import heapq
class Student:
def __init__(self, chinese, math, english):
self.chinese = chinese
self.math = math
self.english = english
self.sum = chinese + math + english
# heapq 是最小堆,成绩好的学生需要被认为是"更小"的
def __lt__(self, other):
if self.sum != other.sum:
return self.sum > other.sum
if self.chinese != other.chinese:
return self.chinese > other.chinese
if self.math != other.math:
return self.math > other.math
return self.english > other.english
# 使用Python的heapq模块实现优先队列
s = []
def insertValue(chinese, math, english):
student = Student(chinese, math, english)
heapq.heappush(s, student)
def deleteValue():
if s:
heapq.heappop(s)
def getTop():
if s:
return s[0]
return None
if __name__ == "__main__":
q = int(input())
for _ in range(q):
line = input().split()
op = int(line[0])
if op == 1:
chinese = int(line[1])
math = int(line[2])
english = int(line[3])
insertValue(chinese, math, english)
elif op == 2:
top = getTop()
if top:
print(f"{top.chinese} {top.math} {top.english}")
elif op == 3:
deleteValue()
算法及复杂度
- 数据结构: 优先队列(最大堆)
- 时间复杂度: 对于
次操作,每次操作(插入、删除)最多花费
时间,其中
是队列中当前的元素数量。查询最大值是
。总时间复杂度为
。
- 空间复杂度:
,在最坏情况下,所有操作都是插入操作,需要存储
个学生对象。