파게로그
[백준 13334번] 철로 본문
문제 링크: 13334번 제목
https://www.acmicpc.net/problem/13334
개선의 여지가 꽤 남아있는 코드이다.
list
는 각 사람들의 'home' 주소의 목록이다. 그리고 59라인에서도 알 수 있듯, 탐색은 'home' 기준으로 진행한다. 왜 그럴까? rail
길이 내에 들어가는 최대 경로(home-office 경로)의 개수를 구하는 과정을 잘 생각해보면, rail
은 반드시 어떤 경로의 'home'에서부터 시작해야 한다. 그렇지 않다면 일부 경로를 포함하지 못하거나, 또는 기껏해야 같은 경로의 수를 포함할 뿐이다.
한편 hq
는, 현재 begin
부터 rail
길이를 봤을 때, 여기에 포함되는 경로들이다. 60라인은 hq
의 경로 중 home
이 begin
보다 작은 것들을 제외하는 과정이다. for문 끝에서 돌아와 begin
이 갱신되었다고 생각할 때, 이들은 제외되어야 하기 때문이다. 64라인은 begin
에 대해 end
를 저장해주는 과정이다. 참고로 문제를 잘 읽어보면 rail
은 엄밀한 의미에서 길이라기보다는... 단순히 office
-home
을 의미한다.
66라인부터는 oq
에서 hq
에 해당하는 경로들을 추가해주는 과정이다. 67라인은 당연히 포함되어야 하고, 68라인도 해당 경로에서 office
-home
과 rail
을 비교한 것인데, 전자가 더 크면 결코 rail
길이 내에 포함될 수 없으므로 이를 제외하는 것은 당연한 것이다.
한편 oq
는 'office' 주소를 기준으로 정렬되어 있는데, office
가 end
보다 더 크다면, 해당 경로를 포함해서 그 뒤의 모든 oq
의 경로들은 당연히 지금 포함될 수 없는 경로들이다.
이러한 조건, 즉 67, 68, 69라인을 모두 통과했다면 이는 범위에 포함되는 경로이므로 hq
에 추가해주고, 이 때 hq
의 크기를 계속해서 갱신해주면, 그 중 최댓값이 정답이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
class Person {
int home;
int office;
public Person(int home, int office) {
this.home = home;
this.office = office;
}
}
class HomeComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
if (o1.home != o2.home) return o1.home - o2.home;
return o1.office - o2.office;
}
}
class OfficeComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
if (o1.office != o2.office) return o1.office - o2.office;
return o1.home - o2.home;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
List<Integer> list = new ArrayList<>();
PriorityQueue<Person> hq = new PriorityQueue<>(new HomeComparator());
PriorityQueue<Person> oq = new PriorityQueue<>(new OfficeComparator());
while (n-- > 0) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
int home = Integer.parseInt(st.nextToken());
int office = Integer.parseInt(st.nextToken());
if (home > office) {
int temp = home;
home = office;
office = temp;
}
list.add(home);
oq.offer(new Person(home, office));
}
Collections.sort(list);
int rail = Integer.parseInt(br.readLine());
int maxSize = 0;
for (int begin : list) {
while (!hq.isEmpty() && hq.peek().home < begin) {
hq.poll();
}
int end = begin + rail;
while (true) {
if (oq.isEmpty()) break;
if (oq.peek().office - oq.peek().home > rail) { oq.poll(); continue; }
if (oq.peek().office > end) break;
Person p = oq.poll();
hq.offer(p);
}
int size = hq.size();
if (size > maxSize) maxSize = size;
}
System.out.println(maxSize);
}
}
'콤퓨타 왕왕기초 > PS' 카테고리의 다른 글
[백준 16724번] 피리 부는 사나이 (1) | 2021.09.17 |
---|---|
[자료구조] 트라이(Trie) (0) | 2021.09.13 |
[백준 1967번] 트리의 지름 (0) | 2021.09.09 |
[프로그래머스 Lv.3] 보석 쇼핑 (0) | 2021.09.03 |
[백준 21316번] 스피카 (0) | 2021.08.14 |