문제


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


풀이


주어진 다각형에 대해, 세 점이 다각형 내부에 있는지 외부에 있는지 판별하면 된다.

다각형이 오목 다각형일 수도 있으므로, CCW만을 이용해서 판별할 수 없다.

이럴 땐 점에서 다각형의 꼭짓점을 지나지 않는 반직선을 그어, 다각형의 변들과 홀수 번 만나는지 짝수 번 만나는지 세보면 된다.

추가로 점이 다각형의 변 위에 있을 때를 예외 처리해 줘야 한다.


코드


import sys


def ccw(x1, y1, x2, y2, x3, y3):
    return (x2 - x1) * (y3 - y2) - (x3 - x2) * (y2 - y1)


def isintersect(x1, y1, x2, y2, x3, y3, x4, y4):
    res1 = ccw(x1, y1, x2, y2, x3, y3)
    res2 = ccw(x1, y1, x2, y2, x4, y4)
    res3 = ccw(x3, y3, x4, y4, x1, y1)
    res4 = ccw(x3, y3, x4, y4, x2, y2)

    if res1 == res2 == res3 == res4 == 0:
        if (max(x1, x2) < min(x3, x4)) or (max(x3, x4) < min(x1, x2)) or (max(y1, y2) < min(y3, y4)) or (max(y3, y4) < min(y1, y2)):
            return 0
        else:
            return 1

    elif (res1 * res2 <= 0) and (res3 * res4 <= 0):
        return 1
    return 0


n = int(sys.stdin.readline())
coord = [tuple(map(int, sys.stdin.readline().split())) for _ in range(n)]

for _ in range(3):
    x, y = map(int, sys.stdin.readline().split())
    z, w = x + 1, y + 1000000001
    meet = 0
    for i in range(-1, n - 1):
        if ccw(x, y, *coord[i], *coord[i + 1]) == 0:
            x1, y1 = coord[i]
            x2, y2 = coord[i + 1]
            if (min(x1, x2) <= x <= max(x1, x2)) and (min(y1, y2) <= y <= max(y1, y2)):
                print(1)
                break
        meet += isintersect(x, y, z, w, *coord[i], *coord[i + 1])
    else:
        print(meet % 2)

Leave a comment