大致题意:
输入所有考生的考号以及所有考生的成绩,以及考生所在的考场号。
输出格式:
考生的考场号 考生的总名次 考生所在的考场号 考生所在考场的名次
首先解决考生的排名问题,应当先对考生在本考场所取得的名次进行排序,再对总体进行一次排序(思路有点类似于基数排序);排序时首先按照成绩进行降序排序,再按照id的字典序排序就可以了;
这个题的难点在于考生名次的计算,解决方法是设置3个变量:
int same = 1;//对于一个成绩,得分相同的考生人数,初始值为1
int pre ; //按照排序结果,前一个考生的成绩
int rank ; //排名
思路:
如果该名考生的成绩与前一个考生的成绩(pre的值)相同,则直接把rank作为该考生的成绩赋值给该考生,并令same加1,表明该多了一个考了pre分的考生;
if(pre == stu.getScore()) {
same ++;
stu.setRank(rank);
}
如果该名考生的成绩与前一个考生的成绩不同,则新的名次为rank + same,同时置same为1;
else{
rank += same;
stu.setRank(rank);
same = 1;
}
这样就解决了重名问题;
具体的JAVA代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
ArrayList<student> buf = new ArrayList<student>(); //buf仅仅暂存一个考场的考生数据
ArrayList<student> List = new ArrayList<student>();//List是所有的数据
int N = sc.nextInt();
int cnt = 0;
for (int i = 1; i <= N; ++i) {
int K = sc.nextInt();
for (int j = 1; j <= K; ++j) {
cnt++;
String id = sc.next();
int score = sc.nextInt();
student stu = new student(id, score, i);
buf.add(stu);
}
int pre = 100000; // 这里每完成一个考场中所有考生的成绩输入,就进行排序
int rank = 0; //获得考场上的排名。首先设置一个超高分100000作为第0名
int same = 1; //考生的得分,这样可以简化代码的逻辑。
Collections.sort(buf);
for (int k = 0; k < buf.size(); ++k) {
student stu = buf.get(k);
if (stu.getScore() != pre) {
rank += same; //
stu.setRank_loc(rank); //考场排名,总排名设置方法类似
same = 1;
pre = stu.getScore(); //及时更新新的得分
} else {
same++;
stu.setRank_loc(rank);
}
}
List.addAll(buf);
buf.clear();
}
Collections.sort(List);
int pre = 10000;
int rank = 0;
int same = 1;
for (int i = 0; i < List.size(); ++i) {
student stu = List.get(i);
if (stu.getScore() != pre) {
rank += same;
stu.setRank_total(rank); //设置总排名
same = 1;
pre = stu.getScore();
} else {
same++;
stu.setRank_total(rank);
}
}
sc.close();
System.out.println(cnt);
for (int i = 0; i < List.size(); ++i) {
student stu = List.get(i);
System.out.println(stu);
}
}
}
class student implements Comparable<student> {
private String id;
private int score;
private int rank_total;
private int rank_loc;
private int loc;
public student(String id, int score, int loc) {
this.id = id;
this.score = score;
this.loc = loc;
}
public int getScore() {
return this.score;
}
public String toString() { //重载输出方法
return (id + " " + rank_total + " " + loc + " " + rank_loc);
}
public void setRank_loc(int rank_loc) { //设置考场排名
this.rank_loc = rank_loc;
}
public void setRank_total(int rank_total) { //设置总排名
this.rank_total = rank_total;
}
private int cmp_score(int a, int b) {
if (a < b)
return 1;
else
return -1;
}
public int compareTo(student stu) {
if (this.score != stu.score) {
return cmp_score(this.score, stu.score);
} else
return this.id.compareTo(stu.id);
}
}