PAT-甲级-1080-Graduate Admission(30)

这篇博文的JAVA代码有一个测试点未通过
在这里插入图片描述

题目描述

It is said that in 2011, there are about 100 graduate schools ready to proceed over 40,000 applications in Zhejiang Province. It would help a lot if you could write a program to automate the admission procedure.

Each applicant will have to provide two grades: the national entrance exam grade GE, and the interview grade GI. The final grade of an applicant is (GE+GI)/2. The admission rules are:

  • The applicants are ranked according to their final grades, and will be admitted one by one from the top of the rank list.
  • If there is a tied final grade, the applicants will be ranked according to their national entrance exam grade GE. If still tied, their ranks must be the same.
  • Each applicant may have K choices and the admission will be done according to his/her choices: if according to the rank list, it is one’s turn to be admitted; and if the quota of one’s most preferred shcool is not exceeded, then one will be admitted to this school, or one’s other choices will be considered one by one in order. If one gets rejected by all of preferred schools, then this unfortunate applicant will be rejected.
  • If there is a tied rank, and if the corresponding applicants are applying to the same school, then that school must admit all the applicants with the same rank, even if its quota will be exceeded.

输入格式:

Each input file contains one test case.

Each case starts with a line containing three positive integers: N (≤40,000), the total number of applicants; M (≤100), the total number of graduate schools; and K (≤5), the number of choices an applicant may have.

In the next line, separated by a space, there are M positive integers. The i-th integer is the quota of the i-th graduate school respectively.

Then N lines follow, each contains 2+K integers separated by a space. The first 2 integers are the applicant’s GE and GI, respectively. The next K integers represent the preferred schools. For the sake of simplicity, we assume that the schools are numbered from 0 to M−1, and the applicants are numbered from 0 to N−1.

输出格式:

For each test case you should output the admission results for all the
graduate schools. The results of each school must occupy a line, which
contains the applicants’ numbers that school admits. The numbers must be
in increasing order and be separated by a space. There must be no extra
space at the end of each line. If no applicant is admitted by a school,
you must output an empty line correspondingly.

输入样例:

11 6 3
2 1 2 2 2 3
100 100 0 1 2
60 60 2 3 5
100 90 0 3 4
90 100 1 2 0
90 90 5 1 3
80 90 1 0 2
80 80 0 1 2
80 80 0 1 2
80 70 1 3 2
70 80 1 2 3
100 100 0 2 4

输出样例:

0 10
3
5 6 7
2 8
			//这就是有个空格输出
1 4

题目信息:

作者: CHEN, Yue

单位: 浙江大学

时间限制: 250 ms

内存限制: 64 MB

代码长度限制: 16 KB

题目大意

这道题大意是讲的学生报考选择学校的过程,写一个程序处理学生的报考信息

第一行输入三个数,依次分别为N:有N位考生报考,M:一共可以报的学校有M个,K:每个考生可以填报K个志愿学校

第二行输入M个数,第i个数代表第i所学校准备录取的人数,即招生额度

接下来N行,每行输入的是一个学生的报考信息有K+2个数,前两个数是GE:初试成绩,GI:面试成绩,接下来的K个数代表所填报的志愿学校

我们要做的是模拟学校录取的过程:

  1. 先按照考生的总分(GE+GI)/2从高到低排序,总分相同的按照GE从高到低排序,如果GE也相同,那么两个学生的排名就相同
  2. 学生从排名最高的开始录取,对于每个考生按照K个志愿的先后顺序考虑
    • 如果当前志愿学校已经招收的人数未达到招生额度,则录取这名学生
    • 如果当前志愿学校已经招满,但是这名学生与该校上一个录取的学生排名相同,那么该学校不管是否收满,都要录取这名学生
    • 如果上面的情况都不满足,当前志愿学校就不能录取这名学生,学生就要转而考虑下一个志愿学校
    • 如果所有志愿学校都无法录取,则这名考生彻底落榜
  3. 最后按照学校的顺序,将每一个学校录取的学生按照原序号递增顺序输出

分析

  • 考生按照总成绩/2进行排序,其实和总成绩排序是相同的,所以我们直接按照总成绩排序
  • 一名学生只能被唯一学校录取
  • 当前志愿学校已经招满时,当前学生与该校上一个录取的学生排名相同则录取,因为我们是按照分数最高到分数最低学生的顺序录取的,所以我们直接比较当前学校最后一名学生的排名与当前学生的排名

注意:

  • 输出的时候输出的是学生的原序号,就是没有排序之前的顺序
  • 输出每个学校学生的序号时,要按照递增的顺序,要把每个学校的学生排一遍,否则最后一个样例出现的就是4 1而不是1 4
  • 没有学校也要输出空行

重点代码步骤

  1. 对于每个学生
  • 按顺序考虑该学生的每个志愿
    • 如果当前志愿没有录满学生,录取该学生
    • 如果当前志愿录满了
      • 如果当前学生与该志愿最后录取的学生排名相同,则也录取当前学生学生
  1. 将每个学校录取的学生按照学生序号从小到大排序,否则最后一个样例就是 4 1而不是1 4
  2. 输出每个学校的学生

代码实现-JAVA

import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main{
	public static void main(String[] args) throws IOException{
		BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
		String[] tempStrArr = bf.readLine().split(" ");
		// N考生
		int N = Integer.parseInt(tempStrArr[0]);
		// M学院
		int M = Integer.parseInt(tempStrArr[1]);
		// K个志愿
		int K = Integer.parseInt(tempStrArr[2]);

		// 每个的学校录取限额
		int[] schoolCon = new int[M];
		tempStrArr = bf.readLine().split(" ");
		for(int i=0; i<M; i++)
			schoolCon[i] = Integer.parseInt(tempStrArr[i]);
		
		// 所有学生
		Student[] allStu = new Student[N];
		for(int i=0; i<N; i++) {
			tempStrArr = bf.readLine().split(" ");
			// 创建学生时给学生序号
			Student newStu = new Student(i,tempStrArr);
			allStu[i] = newStu;
		}
		
		// 按照总分非递增排序,总分相同按照GE排序
		Arrays.sort(allStu);
		// 第一位的同学排名为1
		allStu[0].rank = 1;
		for(int i=1; i<N; i++) {
			// 如果当前的同学与上一位同学的总分和GE都相同则排名相同
			// 相同排名按照 1 2 3 3 5,不连续的这种方式处理
			if((allStu[i].grade == allStu[i-1].grade) && (allStu[i-1].GE == allStu[i].GE)) {
				allStu[i].rank = allStu[i-1].rank;
			}else allStu[i].rank = i+1;
		}

		// 每个学校,学校里放录取的学生
		List<Student>[] school = new List[M];
		for(int i=0; i<M; i++) {
			school[i] = new ArrayList<Student>();
		}
		
		// 对于每个学生
		for(int i=0; i<N; i++) {
		// 按顺序考虑该学生的每个志愿
			for(int j=0; j<K; j++) {
				// 当前学生的当前志愿
				int nowToSchool = allStu[i].toSchool[j];
				// 如果当前志愿没有录满学生
				if(school[nowToSchool].size() < schoolCon[nowToSchool]) {
					// 录取该学生
					school[nowToSchool].add(allStu[i]);
					// 每个学生只能录取一个学校,所以考虑下一个学生
					break;
				}
				else {// 如果当前志愿录满了
				// 如果当前学生与该志愿最后录取的学生排名相同,则也录取当前学生学生
					if(school[nowToSchool].get(school[nowToSchool].size()-1).rank == allStu[i].rank) {
					// 录取该学生
					school[nowToSchool].add(allStu[i]);
					// 每个学生只能录取一个学校,所以考虑下一个学生
					break;
					}
				}
			}
		}
		
		// 将每个学校录取的学生按照学生序号从小到大排序,否则最后一个样例就是 `4 1`而不是`1 4`
		for(int i=0; i<M; i++) {
			Collections.sort(school[i],new Comparator<Student>() {
				public int compare(Student o1, Student o2) {
					return o1.ID - o2.ID;
				}
				
			});
		}
		
		// 输出每个学校的学生
		for(int i=0; i<M; i++) {
			for(int j=0; j<school[i].size(); j++) {
				if(j>0)
					System.out.print(" ");
				System.out.print(school[i].get(j).ID);
			}
			System.out.println();
		}
		
	}
}

class Student implements Comparable<Student>{
	int ID;
	int grade;
	// 志愿学校
	int[] toSchool;
	int GE;
	// 排名
	int rank;
	
	// 将读取到的一整行都输入进行处理
	public Student(int ID, String[] bfRead) {
		this.ID = ID;
		this.GE = Integer.parseInt(bfRead[0]);
		this.grade = GE + Integer.parseInt(bfRead[1]);
		// 给志愿学校赋值
		toSchool = new int[bfRead.length -2];
		for(int i=2; i<bfRead.length; i++) {
			toSchool[i-2] = Integer.parseInt(bfRead[i]);
		}
	}
	
	@Override
	public int compareTo(Student o) {
		// 按总成绩排序
		int s =  o.grade - this.grade;
		if(s == 0) // 总成绩相同按GE排序
			return  o.GE - this.GE;
		else return s;
	}
}
发布了52 篇原创文章 · 获赞 9 · 访问量 6245

猜你喜欢

转载自blog.csdn.net/weixin_43553694/article/details/104180956