problem-2037 今年暑假不AC (java)

这里写图片描述


这道题的难点在于使用怎样的方法挑选出我们可以观看的节目,一般人都会想到先排序,然后再寻找下一个满足开始时间大于等于当前节目的结束时间的节目。但当我们一步一步实现时就会发现很多难点。

首先,排序
每个节目的开始时间和结束时间应该是绑定在一起的,所以我们应该创建一个节目类,然后在创建这样的对象数组,实现对象整体的存取。那么,怎么使ArrayList实现按照对象的某个属性值来排序呢,于是我百度了一下,是让对象实现Comparable接口,或是实例化一个比较器,具体方法如下:

https://zhidao.baidu.com/question/97784478.html?qbl=relate_question_2&word=AyyayList%20%D4%F5%C3%B4%CA%B5%CF%D6%B0%B4%D5%D5%B6%D4%CF%F3%B5%C4%C4%B3%D6%B5%C5%C5%D0%F2

接下来就是对哪一个值进行排序了,一般我们会选择对开始时间进行排序,可是这么做过的同学都会遇到和我一样的问题,那就是当某个节目过长的时候,中间会漏掉好几个可以观看的节目,比如题目给出的例子中
4 14 这个节目观看的话 会漏掉中间可以观看的两个节目。本人小白,还在想该怎么解决这个难题呢就发现这是一道贪心算法的经典题型,越早结束的节目当然要先看啦,按照这样的方法处理 这才是最优的方法。
所以关键的地方在于,按照节目结束的时间进行升序排列,最后再寻找下一个节目的开始时间大于等于当前节目就可以啦!
小白的代码不够简洁,但终于还是AC啦

import java.util.*;

public class Main{ 

        public static void main(String[] args){
            //实例化一个比较器
            Comparator<pro> com=new Comparator<pro>(){
                //重写比较方法
                public int compare(pro p1,pro p2){
                    if(p1.y!=p2.y)//先按照节目结束时间排序
                    {
                        return p1.y-p2.y;
                    }
                    else//若结束时间相同,则按照开始时间排序
                    {
                        return p1.x-p2.x;
                    }

                    }
            };

            Scanner sc=new Scanner(System.in);
            while(sc.hasNext())
            {
                int n=sc.nextInt();
                if(n == 0)
                {  
                    break;  
                }  
                List<pro> list=new ArrayList<pro>();
                for(int i=0;i<n;i++)
                {
                    int x=sc.nextInt();
                    int y=sc.nextInt();
                    pro p=new pro(x,y);
                    list.add(p);//将每个对象存入数组
                }

                Collections.sort(list,com);//按照规则升序排序
                int m=list.get(0).y;//记录第一个节目的结束时间
                int index=1;//记录可以观看的节目数
                for(int i=1;i<n;i++)
                {
                        if(list.get(i).x>=m)//若存在下一个节目的开始时间大于等于当前节目的结束时间,则该节目可观看
                        {

                            index++;
                            m=list.get(i).y;//将该节目结束时间记录下来,以便下一次比较
                        }

                }
                System.out.println(index);

            }

        }


}

class pro
{
        int x;
        int     y;

        public pro(int x,int y)
        {
                this.x=x;
                this.y=y;   
        }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值