题目描述



相关链接:https://www.luogu.com.cn/problem/P1803

解析

这道题对于java来说,第一思路应该是贪心算法,创建一个二维数组(或者创建两个数组),然后对结束时间进行排序(这种情况一般用冒泡排序),所以我刚开始是这么做的,附上代码:

import java.util.Scanner;/*** @author :Zeeland* @date :Created in 2021/4/5 12:58* @version: 1.0$*/public class P1803 {public static void main(String[] args) {Scanner s =new Scanner(System.in);while(s.hasNext()){int n =s.nextInt();int arr[][] =new int[2][n];//initializefor (int i = 0; i < n; i++) {arr[0][i]= s.nextInt();arr[1][i]= s.nextInt();}//sort arr[1][i]int temp =0;for(int i =arr[0].length-1;i>=0;i--){for(int j=0;j<i;j++){if(arr[1][j]>arr[1][j+1]){temp = arr[1][j];arr[1][j] =arr[1][j+1];arr[1][j+1] = temp;temp = arr[0][j];arr[0][j] =arr[0][j+1];arr[0][j+1] = temp;}}}int count =1;
//            for (int i = 0; i < arr[0].length; i++) {//                System.out.println(arr[0][i]+" "+arr[1][i]);
//            }int mid = arr[1][0];for(int i=0;i<arr[0].length;i++){//结束时间小于开始时间if(i<(arr[0].length-1)&& mid<=arr[0][i+1]){count ++;mid = arr[1][i+1];}}System.out.println(count);}}
}

然后就…

因为冒泡排序的时间复杂度为O(n^2),所以10e6数量级的冒泡排序对于java来说还是太难承受了,难免会超时。

这个时候我想到了用树来排序,TreeSet的底层数据结构就是红黑树,时间复杂度O(logn),对于O(n^2)的时间复杂度来说,已经是一个很大的进步了,因此这一次,我选择将beginTime和endTime放在一个node里面,然后treeSet,通过重写比较器或者实现comparable接口来自定义比较的功能。

代码如下:

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;/*** @author :Zeeland* @date :Created in 2021/4/5 14:29* @version: 1.0$*/public class P1803_2 {public static void main(String[] args) {Scanner s =new Scanner(System.in);while(s.hasNext()){int n=s.nextInt();TreeSet<P1803_node> set =new TreeSet<>();for (int i = 0; i < n; i++) {set.add(new P1803_node(s.nextInt(),s.nextInt()));}int count =0;int end =-1;for (P1803_node p1803_node : set) {//如果A结束的时间小于等于B开始的时间if(end <= p1803_node.beginTime){count++;end = p1803_node.endTime;}}System.out.println(count);}}
}class P1803_node implements Comparable<P1803_node>{int beginTime;int endTime;public P1803_node(int beginTime,int endTime){this.beginTime = beginTime;this.endTime = endTime;}//重写toString用于调试@Overridepublic String toString() {return beginTime+" "+endTime;}@Overridepublic int compareTo(P1803_node o) {if(o.endTime==this.endTime){//如果结束时间相等,则比较开始时间,谁小谁在前return this.beginTime- o.beginTime;}else{return this.endTime - o.endTime;}}
}

最后…


虽然全部AC了,但是当我看到有人用java跑出700ms的时候,我就知道还有优化的方法,因此我尝试实现comparator接口比较一下两个比较器之间的运行速度。
代码如下:

import java.util.Comparator;
import java.util.Scanner;
import java.util.TreeSet;/*** @author :Zeeland* @date :Created in 2021/4/5 14:29* @version: 1.0$*/public class P1803_2 {public static void main(String[] args) {Scanner s =new Scanner(System.in);while(s.hasNext()){int n=s.nextInt();TreeSet<P1803_node> set =new TreeSet<>(new P1803_comparator());for (int i = 0; i < n; i++) {set.add(new P1803_node(s.nextInt(),s.nextInt()));}int count =0;int end =-1;for (P1803_node p1803_node : set) {//如果A结束的时间小于等于B开始的时间if(end <= p1803_node.beginTime){count++;end = p1803_node.endTime;}}System.out.println(count);}}
}class P1803_node{int beginTime;int endTime;public P1803_node(int beginTime,int endTime){this.beginTime = beginTime;this.endTime = endTime;}//重写toString用于调试@Overridepublic String toString() {return beginTime+" "+endTime;}
}
class P1803_comparator implements Comparator<P1803_node> {@Overridepublic int compare(P1803_node o1, P1803_node o2){if(o1.endTime==o2.endTime){return o1.beginTime-o2.beginTime;}return o1.endTime-o2.endTime;}
}

最后发现,两者时间差不多,并不是比较器的问题。

那么就只有将Scanner转换为缓冲输入流来实现更加快速地读取了。

代码如下:

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.TreeSet;
import java.util.Comparator;
/*** @author :Zeeland* @date :Created in 2021/4/5 19:24* @version: 1.0$*/public class Main {public static void main(String[] args) throws Exception {BufferedReader bufferedReader =new BufferedReader(new InputStreamReader(System.in));int n = Integer.parseInt(bufferedReader.readLine());TreeSet<P1803_node> set =new TreeSet<>(new P1803_comparator());for (int i = 0; i < n; i++) {String arr[] =bufferedReader.readLine().split(" ");set.add(new P1803_node(Integer.parseInt(arr[0]),Integer.parseInt(arr[1])));}int count =0;int end =-1;for (P1803_node p1803_node : set) {//如果A结束的时间小于等于B开始的时间if(end <= p1803_node.beginTime){count++;end = p1803_node.endTime;}}System.out.println(count);}
}
class P1803_node{int beginTime;int endTime;public P1803_node(int beginTime,int endTime){this.beginTime = beginTime;this.endTime = endTime;}//重写toString用于调试@Overridepublic String toString() {return beginTime+" "+endTime;}
}
class P1803_comparator implements Comparator<P1803_node> {@Overridepublic int compare(P1803_node o1, P1803_node o2){if(o1.endTime==o2.endTime){return o1.beginTime-o2.beginTime;}return o1.endTime-o2.endTime;}
}

最后…

芜湖~

总结

(1)在排序的时候,有三个考虑的方向:Arrays.sort方法,常见的几种排序算法、用TreeSet实现Comparable。
(2)如果有大规模数据输入的时候,用缓冲流输入,会减少很多时间。

关于贪心算法相关的例题:
1.https://www.luogu.com.cn/problem/P1223
2.http://acm.hdu.edu.cn/showproblem.php?pid=2037

整理不易,如果你认为我写的还不错,点赞评论转发收藏~

贪心算法:洛谷P1803凌乱的yyy解析(java)相关推荐

  1. 信息学奥赛一本通 1323:【例6.5】活动选择 | 1422:【例题1】活动安排 | 洛谷 P1803 凌乱的yyy / 线段覆盖

    [题目链接] ybt 1323:[例6.5]活动选择 ybt 1422:[例题1]活动安排 洛谷 P1803 凌乱的yyy / 线段覆盖 注意:ybt 1323数据个数最大为 1 0 3 10^3 1 ...

  2. 洛谷 P1803 凌乱的yyy

    P1803 凌乱的yyy 题目网址:https://www.luogu.com.cn/problem/P1803 题目描述: 给出比赛的时间段,求能够参加比赛的最大数目. 输入输出: 输入:第一行是一 ...

  3. 贪心算法——洛谷(P1803)

    这道题目官方说的是 线段覆盖 的问题,我觉得还是和区间调度一样 采取结构体存放比赛开始和结束时间,用sort排序,自定义cmp, 将结束时间从小到大排序,然后依次选择符合的,即为最终答案 此题为典型的 ...

  4. 洛谷---P1803 凌乱的yyy / 线段覆盖

    题目背景 快 noip 了,yyy 很紧张! 题目描述 现在各大 oj 上有 n 个比赛,每个比赛的开始.结束的时间点是知道的. yyy 认为,参加越多的比赛,noip 就能考的越好(假的). 所以, ...

  5. 洛谷—— P1803 凌乱的yyy

    https://www.luogu.org/problem/show?pid=1803 题目背景 快noip了,yyy很紧张! 题目描述 现在各大oj上有n个比赛,每个比赛的开始.结束的时间点是知道的 ...

  6. 贪心算法——洛谷(P1478)陶陶摘苹果

    我们看一下,在这个题里,所有苹果费力气也就是占背包空间不同,但是价值都是1.背包问题主要是为了解决拿得多却不一定价值最大,拿价值大的却可能装不下其他有价值的东西而使人陷入两难才被发明的算法.对于价值相 ...

  7. 贪心算法——洛谷(P1090)[NOIP2004]合并果子

    该题目也属于经典的贪心算法,在这里熟悉C++里优先队列的使用. 需要导入头文件:   #include<queue> 从这个问题可以深挖出神奇的哈夫曼树问题. 因为这题里合并的是二叉树,所 ...

  8. 贪心算法——洛谷(P4995)跳跳!

    很简单的一道题,就是排序之后贪心+模拟: 先将台阶的高度从小到大排序,注意0也算,但是不是输入进去的: 每次从距离 最小和最大值之间跳跃, 从最小跳到最大之后,最大值不变,最小的下标+1,从最大跳到最 ...

  9. 贪心算法——洛谷(P1094)纪念品分组

    读入之后先用sort排序,然后用两个指针一起向中间走,每次选择都尽可能的让当前状态下最大的和最小的分在一组,如果不行就最大的单独分一组,这样贪心下来就是最少分的组了.证明如下: 如果最大的a[r]不与 ...

最新文章

  1. Android Studio 中删除项目和项目找回------ Project Structure的使用
  2. PHP的方法重载实现
  3. OpenCASCADE绘制测试线束:OCAF 命令之数据框架命令
  4. Spring容器初始化实现V1 版本
  5. Maven的-pl -am -amd参数学习
  6. fifa15服务器位置,《FIFA 15》全系统教程图文攻略
  7. centos图形化桌面的文件在哪_CentOS 安装图形桌面
  8. 保姆级!!前端必会Taro入门级教学!!
  9. opencv图像处理中的一些滤波器+利用滤波器提取条形码(解析二维码)+公交卡倾斜矫正+物体尺寸丈量
  10. Pentaho Data Integration - Kettle 入门指南
  11. 什么?你还不知道IDEA Debug界面的按钮都是干啥用的?快进来补补课~
  12. Linux中设置tab4个空格,linux下vim中tab设置为4个空格例子
  13. Excel函数实战技巧精粹(五)LEN和LENB等函数之常用用法
  14. 【“玩物立志”-scratch少儿编程】迷宫游戏-图片素材
  15. 阿里云服务安装FTP服务器报200 227 entering passive mode(被动模式)错误
  16. 电磁波传播matlab程序,电磁波在不同介质中传播的 MATLAB 仿真教学实践论文
  17. 关于locahost:8080一直在等待却不报错
  18. 【Unity】Google内购
  19. 活动预告 | 伍鸣博士受邀参加深链财经“2020非共识大会”
  20. elementUI使用卡槽二次封装table(亲测可用)

热门文章

  1. 2.8.5Django项目 --图书管理系统(BMS)
  2. zypper 删除mysql_Zypper软件包管理教程----(一)简介及软件查询
  3. 【CSS】CSS字体样式【CSS基础知识详解】
  4. 概率统计——基础运算法则
  5. 【Paper】2022_离散时间多智能体系统编队-包围控制研究_李博凡
  6. 浅谈《3D打印:三维智能数字化创造》读后感和一些感想
  7. Kubernetes 应用部署实战
  8. 友好的搜索引擎URL地址
  9. 人工智能如何为传统产业赋能?| 活动
  10. Eclipse中文注释乱码解决