https://www.acmicpc.net/problem/11000



greedy를 이용한다.
시작시간을 기준으로 오름차순 정렬을 한다.(시작시간이 같을 경우 종료시간을 기준으로 오름차순 정렬을 한다.)
정렬된 배열을 돌면서 시작시간과 우선순위큐에 있는 가장 작은 값을 비교한다.
peek()의 값이 시작시간보다 크거나 같은 경우 poll()을 해주고 종료시간을 offer()해준다.
peek()의 값이 시작시간보다 작은 경우 종료시간을 offer()해준다.
우선순위큐에 남은 값들이 강의실의 개수이다.
/**
* 11000_강의실 배정
*
* 시작시간을 기준으로 오름차순 정렬을 한다.
* 시작시간이 같을 경우 종료시간을 기준으로 오름차순 정렬을 한다.
* 우선순위큐에 종료시간을 넣는다.
* 우선순위큐의 peek()을 이용해 주어진 배열을 돌면서 비교한다.
* peek()의 값이 다음 데이터의 시작시간보다 크거나 같은 경우 poll()을 해주고 데이터의 종료시간을 넣는다.
* 답은 우선순위큐에 남아있는 데이터의 갯수(pq.size())이다.
*/
public class P_11000 {
static int N;
static Time[] input; // 주어진 시작시간, 종료시간 담는 배열
static PriorityQueue<Integer> pq;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
input = new Time[N];
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine());
input[i] = new Time(Integer.parseInt(st.nextToken()), Integer.parseInt(st.nextToken()));
}
Arrays.sort(input);
pq = new PriorityQueue<>();
pq.offer(input[0].e);
for (int i = 1; i < input.length; i++) {
// 우선순위큐에서 가장 작은 값
int tmp = pq.peek();
// 시작시간 < 우선순위큐의 가장 작은 값
// 종료시간을 우선순위큐에 넣는다.
if (input[i].s < tmp) {
pq.offer(input[i].e);
}
// 시작시간 >= 우선순위큐의 가장 작은 값
// 우선순위큐의 가장 작은 값을 빼고 종료시간을 넣는다.
else {
pq.poll();
pq.offer(input[i].e);
}
}
System.out.println(pq.size());
}
static class Time implements Comparable<Time>{
int s; // 시작시간
int e; // 종료시간
public Time(int s, int e) {
this.s = s;
this.e = e;
}
// 시작시간을 기준으로 오름차순 정렬
// 시작시간이 같을 경우 종료시간을 기준으로 오름차순 정렬
@Override
public int compareTo(Time o) {
if (this.s == o.s) {
return this.e - o.e;
}
return this.s - o.s;
}
}
}