BOJ 12771 - Oil

image.png

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

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

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

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

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

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

image.png

1년만의 재도전

1111퍼 까지 가다 틀려버렸다.

구현이 잘못된것 같다.

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

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

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

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

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

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


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

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

image.png

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

뭐가문젠가…

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

ㅅㅂ 출제자 인성 어디?

image.png

Tags:

Categories:

Updated:

Comments