기록하는삶

[코딩 테스트 연습(파이썬/Python)] 백준 11758번 _ CCW(Counter Clockwise) 본문

백준(Python)/기하학(Geometry)

[코딩 테스트 연습(파이썬/Python)] 백준 11758번 _ CCW(Counter Clockwise)

mingchin 2021. 12. 27. 23:54
728x90
반응형

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

 

11758번: CCW

첫째 줄에 P1의 (x1, y1), 둘째 줄에 P2의 (x2, y2), 셋째 줄에 P3의 (x3, y3)가 주어진다. (-10,000 ≤ x1, y1, x2, y2, x3, y3 ≤ 10,000) 모든 좌표는 정수이다. P1, P2, P3의 좌표는 서로 다르다.

www.acmicpc.net

[문제]

2차원 좌표 평면 위에 있는 점 3개 P1, P2, P3가 주어진다. P1, P2, P3를 순서대로 이은 선분이 어떤 방향을 이루고 있는지 구하는 프로그램을 작성하시오.

 

[입력]

첫째 줄에 P1의 (x1, y1), 둘째 줄에 P2의 (x2, y2), 셋째 줄에 P3의 (x3, y3)가 주어진다. (-10,000 ≤ x1, y1, x2, y2, x3, y3 ≤ 10,000) 모든 좌표는 정수이다. P1, P2, P3의 좌표는 서로 다르다.

[출력]

P1, P2, P3를 순서대로 이은 선분이 반시계 방향을 나타내면 1, 시계 방향이면 -1, 일직선이면 0을 출력한다.

 

[아이디어]

1) P1, P2로 만든 직선을 기준으로 P3의 상대적 위치가 방향을 정한다.

2) 기울기 생성이 불가한 경우 예외처리가 필요하다.

3***) 그러니까 그냥 외적을 쓰자^

 

a,b=map(int,input().split())
c,d=map(int,input().split())
e,f=map(int,input().split())
if c-a==0:
    if e-c==0:
        print(0)
    else:
        print(1 if (e-c)*(d-b)<0 else -1)
else:
    if e-c==0:
        print(1 if (c-a)*(f-d)>0 else -1)
    else:
        p=(d-b)/(c-a)
        k = f-p*(e-a)-b
        if p==(f-d)/(e-c):
            print(0)
        elif c-a>0:
            print(1 if k>0 else -1)
        else:
            print(-1 if k>0 else 1)

나의 순수한 뇌가 외적(cross product/outer product)따위 생각하지 않았기에 고생을 했다,,^^ 아이디어 그대로 기울기 계산이 불가한 경우에 대한 예외처리 및 그 경우를 제외하고 방향성에 대한 처리를 해줬다.

 

# 외적 활용
a,b=map(int,input().split())
c,d=map(int,input().split())
e,f=map(int,input().split())
x=(c-a)*(f-b)-(e-a)*(d-b)
print(x and x//abs(x))

 

그림에서 가장 아래의 점부터 순서대로 P1, P2, P3라 하면 만들어 지는 두 벡터와 그 외적은 아래와 같다.

이때 저 외적의 결과 x의 값에 따라 선분 P2P3가 만들어내는 방향성이 달라진다.

① x=0인 경우: 일직선

② x>0인 경우: 반시계 방향

③ x<0인 경우: 시계 방향

 

따라서 맨 마지막 줄 처럼 표현함으로써, x가 0인 경우에는 0을 출력하고 그렇지 않은 경우에는 양수이면 1, 음수이면 -1을 출력하도록 한 것이다. x가 0인 경우에는 x//abs(x) 자체가 동작할 수 없는데, 마치 try-except 구문처럼 뒤의 값이 False 뿐만 아니라 error가 발생할 때도 앞의 값을 출력하게 할 수 있는지 처음 알게되었다.

 

728x90
반응형