pat德才论(java)
原创
©著作权归作者所有:来自51CTO博客作者公众号bigsai的原创作品,请联系作者获取转载授权,否则将追究法律责任
刷pat时候发现德才论这个题目真有点烦。用到的知识点比较重要。题目链接 题意:
链接:https://www.nowcoder.com/questionTerminal/97b6a49a85944650b2e3d0660b91c324
/**
- 德才论
- 题目描述
- 宋代史学家司马光在《资治通鉴》中有一段著名的“德才论”:“是故才德全尽谓之圣人,才德兼亡谓之愚人,
- 德胜才谓之君子,才胜德谓之小人。凡取人之术,苟不得圣人,君子而与之,与其得小人,不若得愚人。”
- 现给出一批考生的德才分数,请根据司马光的理论给出录取排名。
- 输入描述:
- 输入第1行给出3个正整数,分别为:N(<=105),即考生总数;L(>=60),为录取最低分数线,即德分
- 和才分均不低于L的考生才有资格被考虑录取;H(<100),为优先录取线——德分和才分均不低于此线的被
- 定义为“才德全尽”,此类考生按德才总分从高到低排序;才分不到但德分到线的一类考生属于“德胜才”,
- 也按总分排序,但排在第一类考生之后;德才分均低于H,但是德分不低于才分的考生属于“才德兼亡”但尚
- 有“德胜才”者,按总分排序,但排在第二类考生之后;其他达到最低线L的考生也按总分排序,但排在第三
- 类考生之后。随后N行,每行给出一位考生的信息,包括:准考证号、德分、才分,其中准考证号为8位整数,
- 德才分为区间[0, 100]内的整数。数字间以空格分隔。
- 输出描述:
- 输出第1行首先给出达到最低分数线的考生人数M,随后M行,每行按照输入格式输出一位考生的信息,考生
- 按输入中说明的规则从高到低排序。当某类考生中有多人总分相同时,按其德分降序排列;若德分也并列,
- 则按准考证号的升序输出。
- 输入例子:
- 14 60 80
- 10000001 64 90
- 10000002 90 60
- 10000011 85 80
- 10000003 85 80
- 10000004 80 85
- 10000005 82 77
- 10000006 83 76
- 10000007 90 78
- 10000008 75 79
- 10000009 59 90
- 10000010 88 45
- 10000012 80 100
- 10000013 90 99
- 10000014 66 60
- 输出例子:
- 12
- 10000013 90 99
- 10000012 80 100
- 10000003 85 80
- 10000011 85 80
- 10000004 80 85
- 10000007 90 78
- 10000006 83 76
- 10000005 82 77
- 10000002 90 60
- 10000014 66 60
- 10000008 75 79
- 10000001 64 90
*/
总体思路:建立一个类包含学号,得分,和才分。用四种集合分别存入输入的符合题意的。然后对集合进行自定义快排。
但是我不是这么想的,我想利用优先队列让他自动排序。我只需要设置他是大根堆还是小根堆就行了。代码如下:
package 乙;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Scanner;
public class pat5 {
public static void main(String[] args) throws IOException {
//BufferedReader sc=new BufferedReader(new InputStreamReader(System.in));
//Scanner sc=new Scanner(System.in);
StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
in.nextToken();int allcount=(int)in.nval;//总人数
int count=0;//满足条件的人数
in.nextToken();int last=(int)in.nval;//最低分
in.nextToken();int well=(int)in.nval;//德才优秀
student stu[]=new student[allcount];
Queue<student> c1 = new PriorityQueue<>(cmp1);//德才兼备
Queue<student> c2 = new PriorityQueue<>(cmp1);//才分不到但德分到线的一类考生属于“德胜才”
Queue<student> c3 = new PriorityQueue<>(cmp1);//德才分均低于H,但是德分不低于才分的考生属于“才德兼亡”但尚有“德胜才”者
Queue<student> c4 = new PriorityQueue<>(cmp1);//其他
for(int i=0;i<allcount;i++)
{
in.nextToken(); int no1=(int)in.nval;
in.nextToken(); int no2=(int)in.nval;in.nextToken(); int no3=(int)in.nval;
stu[i]=new student(no1,no2,no3);
}
for(int i=0;i<allcount;i++)
{
if(stu[i].de>=last&&stu[i].cai>=last)
{
count++;
if(stu[i].cai>=well&&stu[i].de>=well)
{c1.add(stu[i]);}
else if(stu[i].cai>=last&&stu[i].de>=well)
{c2.add(stu[i]);}
else if(stu[i].de>=stu[i].cai&&stu[i].cai<well)//注意没有才分高于well,得分低于**的选项
{c3.add(stu[i]);}
else
{c4.add(stu[i]);}//其他状况
}
}
out.println(count);
while(!c1.isEmpty())
{
student st=c1.poll();//移除并返回头
out.println(st.number+" "+st.de+" "+st.cai);
}
while(!c2.isEmpty())
{
student st=c2.poll();//移除并返回头
out.println(st.number+" "+st.de+" "+st.cai);
}
while(!c3.isEmpty())
{
student st=c3.poll();//移除并返回头
out.println(st.number+" "+st.de+" "+st.cai);
}
while(!c4.isEmpty())
{
student st=c4.poll();//移除并返回头
out.println(st.number+" "+st.de+" "+st.cai);
}
out.flush();
}
static Comparator<student>cmp1=new Comparator<student>()
{
public int compare(student a, student b) {
if(a.de+a.cai==b.cai+b.de)//如果总分相同
{
if(a.de==b.de)
{
return a.number-b.number;//按照学号升序
}
else
{return b.de-a.de;}//返回大根堆
}
else
return (int)(b.cai+b.de-a.de-a.cai);//返回大根堆
}
};
static class student
{
int number;
int de;
int cai;
public student(int number,int de,int cai)
{
this.number=number;
this.de=de;
this.cai=cai;
}
}
}
水平有限。。有好想法的多多交流。