한 쪽을 기준으로 한 번 만에 전체 공간을 sweep, 쓸어오는 알고리즘.
기하학적 문제를 해결하는 데 사용되는 알고리즘적 접근 방식.
이 기법은 주어진 문제의 해를 찾기 위해 공간을 선형적으로 스윕(sweep)하면서 데이터를 처리한다.
근데 하나의 큰 선분(0,5)이 있을 때 (1,2)가 들어오면, 그 다음 (2,5)가 들어왔을 때 (0,5)를 어떻게 기억하고 있어야 될지 감이 안옴.
결국 알고리즘 분류를 보고 스위핑(sweeping)
이라는 처음보는 분류가 있었다.
(결국 다른 사람의 풀이를 보았다.)
package solution;
import java.util.*;
import java.io.*;
public class BOJ1689_겹치는선분 {
static class Line implements Comparable<Line> {
int node;
int type; // 시작(0), 끝(1)
Line(int node, int type) {
this.node = node;
this.type = type;
}
@Override
public int compareTo(Line o) {
if (this.node == o.node) return o.type - this.type;
return this.node - o.node;
}
}
static final int START_TYPE = 0;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
int N = Integer.parseInt(br.readLine());
PriorityQueue<Line> lines = new PriorityQueue<>();
for (int i = 0; i < 2 * N; i+=2) {
st = new StringTokenizer(br.readLine());
lines.add(new Line(Integer.parseInt(st.nextToken()), 0));
lines.add(new Line(Integer.parseInt(st.nextToken()), 1));
}
int ans = 1;
int nowCnt = 0;
while(!lines.isEmpty()) {
Line line = lines.poll();
if(line.type == START_TYPE) {
nowCnt++;
ans = Math.max(ans, nowCnt);
} else {
nowCnt--;
}
}
System.out.println(ans);
}
}
처음에 배열에 넣어줬는데, 우선순위 큐에 넣을때가 1초정도 빠르게 나온다.
시작점과 끝점을 함께 가져가는 게 아닌, 이를 분리해서 보는 것이 이 문제의 관건이다.
그리디는 난이도가 높아지면 떠올리는 데 한계가 있다.
스위핑은 이런 선분에서 진행하는 1차원이 있고, 평면에서 진행하는 2차원이 있는데 2차원부터는 난이도가 상당히 높다. (플래티넘)
그리고 찾아보니 세그먼트 트리
를 활용하는 문제가 많다고 한다.
다음은 너다..