PAT 1025 PAT Ranking题解

大致题意:

输入所有考生的考号以及所有考生的成绩,以及考生所在的考场号。

输出格式:

考生的考场号 考生的总名次 考生所在的考场号 考生所在考场的名次

首先解决考生的排名问题,应当先对考生在本考场所取得的名次进行排序,再对总体进行一次排序(思路有点类似于基数排序);排序时首先按照成绩进行降序排序,再按照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);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值