解法一:排序
多标准的排序问题,有个小坑就是分数相同的排名也要相同,分数更低的学生排名就要跳跃了。感觉PAT题目经常隐瞒一些有歧义的地方和数据范围不明说😅。
import java.io.*;
import java.util.*;
public class Main {
// private static float EXP = 1e-5f;
public static void main(String[] args) throws IOException {
StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();
int N = (int) in.nval;
in.nextToken();
int Q = (int) in.nval;
Map<Integer, Student> students = new HashMap<>(N);
int id;
int C, M, E;
for (int i = 0; i < N; ++i) {
in.nextToken();
id = (int) in.nval;
in.nextToken();
C = (int) in.nval;
in.nextToken();
M = (int) in.nval;
in.nextToken();
E = (int) in.nval;
students.put(id, new Student(C, M, E));
}
Comparator<Student> CComparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.C - o1.C;
}
};
Comparator<Student> MComparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.M - o1.M;
}
};
Comparator<Student> EComparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return o2.E - o1.E;
}
};
Comparator<Student> AComparator = new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
return Float.compare(o2.A, o1.A);
}
};
rank(students.values(), AComparator, 'A');
rank(students.values(), CComparator, 'C');
rank(students.values(), MComparator, 'M');
rank(students.values(), EComparator, 'E');
for (int i = 0; i < Q; ++i) {
in.nextToken();
id = (int) in.nval;
if (students.containsKey(id)) {
out.println(students.get(id));
} else {
out.println("N/A");
}
}
out.flush();
}
private static void rank(Collection<Student> students, Comparator<Student> comparator, char type) {
List<Student> list = new ArrayList<>(students);
list.sort(comparator);
list.get(0).updateRank(1, type);
int rank = 1;
for (int i = 1; i < list.size(); ++i) {
switch (type) {
case 'A':
if (list.get(i).A < list.get(i - 1).A) {
rank = i + 1;
}
break;
case 'C':
if (list.get(i).C < list.get(i - 1).C) {
rank = i + 1;
}
break;
case 'M':
if (list.get(i).M < list.get(i - 1).M) {
rank = i + 1;
}
break;
case 'E':
if (list.get(i).E < list.get(i - 1).E) {
rank = i + 1;
}
break;
}
list.get(i).updateRank(rank, type);
}
}
}
class Student {
int C;
int M;
int E;
float A;
int bestRank;
char type;
Student(int C, int M, int E) {
this.C = C;
this.M = M;
this.E = E;
A = (float) (C + M + E) / 3.0f;
bestRank = 0x3f3f3f3f;
}
void updateRank(int rank, char type) {
if (rank < bestRank) {
bestRank = rank;
this.type = type;
}
}
@Override
public String toString() {
return bestRank + " " + type;
}
}