小菜鸡第一次发CSDN,还请大家多多支持,本人专业是软件工程,所以主攻Java,不过Java在竞赛当中有时候卡时间和内存,确实让人头疼,后续我会自学C++,为大家更新两份代码内容,还请大家多多关注咯!!
=======================================================================
没有人没抢过红包吧…… 这里给出N个人之间互相发红包、抢红包的记录,请你统计一下他们抢红包的收获。
输入格式:
输入第一行给出一个正整数N(≤104),即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:
KN1P1⋯NKPK
其中K(0≤K≤20)是发出去的红包个数,Ni是抢到红包的人的编号,Pi(>0)是其抢到的红包金额(以分为单位)。注意:对于同一个人发出的红包,每人最多只能抢1次,不能重复抢。
输出格式:
按照收入金额从高到低的递减顺序输出每个人的编号和收入金额(以元为单位,输出小数点后2位)。每个人的信息占一行,两数字间有1个空格。如果收入金额有并列,则按抢到红包的个数递减输出;如果还有并列,则按个人编号递增输出。
=====================================================================
这个题目其实就是在考查排序的问题,通过简单分析题目,我们要弄清楚是结果排序还是过程中排序,这题很明显是结果排序,所以我们需要根据题意处理数据,并按照要求排序。题目当中最后我标记红色的部分是排序的规则,但是Java中sort函数直接调用的话只能是从小打到排序,因此想要实现更复杂的排序规则则需要重写sort函数。下面我来介绍Java中sort函数比较常用的重写万能模板。
import java.util.Arrays;
public class Main{
public static void main(String[] args){
node[] data = new node[10];
//初始化......
//注意这里node[]数组要进行初始化,否则会有空指针异常
Arrays.sort(data,new Comparator<node>(){
@Override
public int compare(node o1, node o2) {
if(o1.money!=o2.money)return o1.money-o2.money;//升序
else return o2.size-o1.size; //降序
}
});
}
}
class node{
String index;
int money;
int size;
public node(String index, int money,int size){
this.index = index;
this.money = money;
this.size = size;
}
}
在上述代码中,重写Comparator当中compare函数即可实现复杂比较,这里我们如果两个金钱不一样,则比较金钱,注意o1和o2的前后位置关系,如果想要实现升序则与输入参数的位置书序一致,因为返回值如果大于0则表明前者大于后者,返回值如果小于0则表示前者小于后者,而Java默认是按照小于排序。因此,想要实现升序则需要将两个位置互换。如果两个值相等,我们可以启用第二重比较,比较两个规模大小,在上述代码中,则按照规模大小进行降序排序。
好了解完比较器的简单使用规则,我们就可以定义一个简单类来实现任何题目的多重排序问题了。下面是L2-009的代码。
import java.io.*;
import java.util.*;
public class Main{
public static void main(String[] args)throws IOException{
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(in.readLine());
node[] data = new node[N+1];
//初始化数组!!!一定要初始化
for (int i = 0; i <=N ; i++) {data[i] = new node(i,0,0);}
for(int i = 1;i<=N;i++){
String[] s = in.readLine().split(" ");
for(int j =1;j<s.length;j+=2){ //第一个是编号,第二是金钱
data[Integer.parseInt(s[j])].money+=Integer.parseInt(s[j+1]); //记录该编号的金钱变化
data[Integer.parseInt(s[j])].count++; //抢到红包数加一
data[i].money-=Integer.parseInt(s[j+1]); //第i个人少了的钱
}
}
Arrays.sort(data,new Comparator<node>(){
@Override
public int compare(node o1, node o2) {
if(o1.money!=o2.money)return o2.money-o1.money; //金钱降序
else if(o1.count!=o2.count)return o2.count-o1.count;//红包数降序
else return o1.index-o2.index; //编号升序
}
});
for (int i = 0; i <=N ; i++) {
if(data[i].index!=0)//由于我们也将编号0也考虑进去了,但实际情况是没有的,因此要跳过
System.out.printf("%d %.2f\n",data[i].index,data[i].money*1.0/100);
}
}
}
class node{
int index;
int money;
int count;
public node(int index, int money,int count){
this.index = index;
this.money = money;
this.count = count;
}
}
但是由于Java本身的机制问题,导致它运行时间比C++慢很多,因此,这里直接最后一个点TLE了,目前对于Java没有更好的求解方法了,如果有,还请大佬给出。谢谢大家的支持!