九度OJ第1005题,提交AC后,分类到快速排序,等级四。不过我用的是冒泡排序将applicant排序,并且不考虑并列
step1:bubble sort
step2:assign quota 此阶段考虑并列问题。在else中判断。
assign结果存储采用ArrayList。开始想用HashMap或TreeMap后来还是用了ArrayList。感觉自己对Java真的是只会一点皮毛,深一点的集合类,HashMap,HashTable,Vector都没有用过,真应该好好学习练习一下。不过!只要现在认识到,开始学习还不算晚哈!
先贴出我自己写的代码,在jobdu上下载了一份耗时70MS的代码,待我学习下再贴出心得。有些在网上查的方法也在注释中标出来了,方便以后查看。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Test4 {
/**
* by qr jobdu 1005 2014-8-7
*/
public static void main(String[] args) {
/*
* step1:ranking step2:assign quota-----> result:admission results
*/
Scanner scan=new Scanner (System.in);//correct spelling error:ctrl+1
while(scan.hasNext()){
int n=scan.nextInt();//total number of applicants
int m=scan.nextInt();//total number of graduate schools
int k=scan.nextInt();//number of choices an applicant may have
int quota[]=new int[m];//the i-th integer is the quota of the i-th graduate school
for(int i=0;i<m;i++)
quota[i]=scan.nextInt();
int ge[]=new int [n]; //applicant's GE
int gi[]=new int [n]; //applicant's GI
int grade[]=new int [n]; //final grade of an applicant
int rank[]=new int [n]; //number of an applicant sorted in the rank list
int sch[][]=new int [n][k]; //the preferred school
for(int i=0;i<n;i++){
ge[i]=scan.nextInt();
gi[i]=scan.nextInt();
grade[i]=(ge[i]+gi[i])/2;
rank[i]=i;
for(int j=0;j<k;j++)
sch[i][j]=scan.nextInt();
}
//step1:ranking ---> method :sort in non-increasing way
for(int i=0;i<n-1;i++){ //bubble sort
for(int j=i+1;j<n;j++){
int num=compare(grade[i],grade[j],ge[i],ge[j]);
if(num==-1){
int temp=grade[i];
grade[i]=grade[j];
grade[j]=temp;
temp=rank[i];
rank[i]=rank[j];
rank[j]=temp;
}
}
}
// for(int i=0;i<n;i++){
// System.out.println(grade[i]+"\t"+rank[i]);
// }
//step2:assign quota ---> use ArrayList instead of Chain
ArrayList<Integer> result[]=new ArrayList[m];// applicant number for each school
for(int i=0;i<m;i++){
result[i]=new ArrayList(); // do not forget to initialize when the type of array is object
}
for(int i=0;i<n;i++){
for(int j=0;j<k;j++){
int appnum=rank[i]; //applicant number
int schnum=sch[appnum][j]; //school number
if(quota[schnum]>0){
quota[schnum]--;
result[schnum].add(appnum);
break; //break make no effect on if-else
}else { //如果没有配额了,但是这个人和他上一个是相同排名,并且选择了同一个学校,则可以分配到这个学校。
int lastappnum=rank[i-1]; //last applicant's number
int grade1=grade[i-1];
int grade2=grade[i];
int ge1=ge[lastappnum];
int ge2=ge[appnum];
if(compare(grade1,grade2,ge1,ge2)==0 && result[schnum].contains(lastappnum)){ //两者排名相同并且选了同一个学校(contains 判断)
result[schnum].add(appnum);
break;
}
}
}
}
//step3:output the result
for(int i=0;i<m;i++){
Integer [] array=new Integer [result[i].size()];
result[i].toArray(array); //toArray-->transfer arraylist to array
Arrays.sort(array);
for(int j=0;j<array.length;j++){
System.out.print(array[j]);
if(j!=(array.length-1))
System.out.print(" ");
}
System.out.println();
}
}
}
//rank the applicant
private static int compare(int grade1, int grade2, int ge1, int ge2) {
if(grade1>grade2)
return 1; //i位于j之前
else if(grade1<grade2)
return -1; //i位于j之后
else{
if(ge1>ge2)
return 1; //i位于j之前
else if(ge1<ge2)
return -1; //i位于j之后
else
return 0; //i,j排名相同
}
}
}
自己写得比较菜鸟啦。。希望大家多多批评指正!
感觉如果用快速排序是不是太麻烦了,虽然它是冒泡排序的变种。。。不过还是没有用。欢迎大家和我讨论呀!