天体赛L2-009 抢红包(Java)

文章讲述了作者作为软件工程专业的Java开发者,遇到红包问题比赛中的内存和时间限制,决定学习C++。内容涉及N人红包发放和接收的记录处理,Java中的Comparator重写以实现复杂排序,以及Java性能相较于C++的局限。
摘要由CSDN通过智能技术生成

        小菜鸡第一次发CSDN,还请大家多多支持,本人专业是软件工程,所以主攻Java,不过Java在竞赛当中有时候卡时间和内存,确实让人头疼,后续我会自学C++,为大家更新两份代码内容,还请大家多多关注咯!!

=======================================================================

没有人没抢过红包吧…… 这里给出N个人之间互相发红包、抢红包的记录,请你统计一下他们抢红包的收获。

输入格式:

输入第一行给出一个正整数N(≤104),即参与发红包和抢红包的总人数,则这些人从1到N编号。随后N行,第i行给出编号为i的人发红包的记录,格式如下:

KN1​P1​⋯NK​PK​

其中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没有更好的求解方法了,如果有,还请大佬给出。谢谢大家的支持!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值