2023河南萌新联赛第(四)场:河南大学 I - yh的线段
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
yh喜欢好线段,好线段即两条线段相交且不与其他线段重合的线段。
两条线段 [ l 1 , r 1 ] [l_1,r_1] [l1,r1]和 ∣ l 2 , r 2 ] |l_2,r_2] ∣l2,r2]相交(如果存在至少一个 x x x ,使得 l 1 < = x < = r 1 l_1<=x<=r_1 l1<=x<=r1和 l 2 < = x < = r 2 l_2<=x<=r_2 l2<=x<=r2 ,则认为两个线段相交)。
yh在数轴上有几条线段,他可以把在数轴上相交的线段结合,但是对于每个线段只能与其它线段结合一次,且不能与其它线段有重合部分,yh可以舍弃任何数量的线段
给你
n
(
2
<
n
<
1
e
6
)
n(2<n<1e6)
n(2<n<1e6) 条线段,如果两条线段相交不与其他线段相交,则由这两条线段组成的线段被称为好线段,线段不能被重复使用,但可以被舍弃任意数量的线段,请你找出好线段个数的最大值。
输入描述:
第一行包含一个正数
n
(
2
<
n
<
l
e
6
)
n (2< n< le6)
n(2<n<le6) ———— 线段的个数。
接下来
n
n
n 行各包含两个整数
l
i
l_i
li 和
r
i
r_i
ri (
0
<
=
l
i
<
=
r
i
<
=
1
0
9
0<=l_i<=r_i<=10^9
0<=li<=ri<=109),表示
n
n
n 个线段。
输出描述:
输出好线段个数的最大值。
示例1
输入
5
2 2
2 8
0 10
1 2
5 6
输出
1
示例2
输入
7
2 4
9 12
2 4
7 7
4 8
10 13
6 8
输出
3
说明
对于样例2,我们可以删除[4,8]这一条线段,然后将[2,4]和[2,4]、[6,8]和[7,7]、[9,12]和[10,13]组成三条好线段,可以看出这是最优的情况。
import java.io.*;
import java.util.ArrayList;
import java.util.Collections;
class Node implements Comparable<Node> {
int l, r;
public Node(int l, int r) {
this.l = l;
this.r = r;
}
@Override
public int compareTo(Node o) {
return Integer.compare(this.r, o.r);
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int n = Integer.parseInt(bf.readLine());
ArrayList<Node> arrayList = new ArrayList<>();
for (int i = 0; i < n; i++) {
String[] str = bf.readLine().split(" ");
int l = Integer.parseInt(str[0]);
int r = Integer.parseInt(str[1]);
arrayList.add(new Node(l, r));
}
//对于重复相交的线段我们只用统计一次即可,因为可以删除任何数量的线段,
//为了找出最大数量的好线段,我们可以按线段的右端点排序存储,然后遍历统计即可
Collections.sort(arrayList);
int ans = 0;
int f = -1, l = -1;
for (Node ai : arrayList) {
if (ai.l <= f) continue;
if (ai.l <= l) {
ans++;
f = ai.r;
} else l = ai.r;
}
bw.write(String.valueOf(ans));
bw.close();
}
}