BOJ 12771 - Oil

image.png

항상 정답이 되는 직선은 어떤 두 직선의 양 끝점을 잇는다고 가정하자.

naive하게는 $O(n^3)$이 걸린다. 직선들의 양 끝점 두 개를 잡고 다른 모든 직선들에 대해 겹치는지 검사를 할 수 있기 때문이다.

이걸 $O(n^2 \log n)$ 으로 줄이면 이 문제를 풀 수 있다.

모든 $2n$ 개의 점에 대해 돌면서 다른 모든 점들을 각도순으로 정렬하고 스위핑을 한다고 하면,

$O(2n \cdot \log (2n) \cdot 2n)$ 이므로 풀 수 있을 것 같다.

이 방법으로 시도해보겠다.

image.png

1년만의 재도전

$11$퍼 까지 가다 틀려버렸다.

구현이 잘못된것 같다.

Graham Scan처럼 가장 왼쪽 점을 기준으로 잡고 CCW에 따라 정렬하는 것 이 아닌 점들 중 임의의 점을 기준으로 $360 \degree$ 로 정렬을 해야하기 때문에 까다롭다.

요지는 어떤 구간이 $[x_1,x_2]$ 라면 항상 $x_1$에 더해줘야하고 $x_2$에 빼줘야하지 않고 도는 방향에 따라 반대가 될 수도 있다는 것이다.

또한 360도로 정렬하는 글도 참고했다.

두 구간으로 나눈다음에 정렬하면 된다고 한다.

나는 오른쪽 반직선을 시작으로 시계방향으로 $360 \degree$를 돌릴 것이므로 $1,2$ 사분면과 $3,4$ 사분면을 각각 정렬해줄 것이다.

그리고 이 문제에서도 항상 직선은 지표면과 닿아야 하므로 동일한 $y$ 에 대해서 직선을 그을 수 없기 때문에 그것이 더 알맞다.


추가적으로 구현에서 잘못 생각한 것은 360도 스위핑을 해줄 필요가 없었다는 것이다.

왜냐면 $y<0$ 이라면 기준점 대칭을 통해 $y>0$ 으로 만들어줘서 $180 \degree$에 대해서만 스위핑해줄 수 있다.

image.png

이렇게 구현하고 제출하니 $46$퍼에서 WA가 나왔다.

뭐가문젠가…

Assert 문을 찍어보다가 놀라운 사실을 발견했는데 $x_1 > x_2$ 인 경우가 있다는 것이다.

ㅅㅂ 출제자 인성 어디?

image.png

Tags:

Categories:

Updated:

Comments