• CCW
    • 점 3개가 있을 때 이 3점을 이은 방향을 알고자 할 때 쓰는 알고리즘
    • https://www.acmicpc.net/blog/view/27
    • 두점을 잇는 직선 2개의 벡터들을 외적했을 때
      • 값이 -1이면 세점은 시계방향으로 회전
      • 값이 0 이면 세점은 한 직선위에
      • 값이 1이면 세점은 반시계방향으로 회전한다
def ccw(a, b, c):
    return (b[0] - a[0])*(c[1] - a[1])-(c[0] - a[0])*(b[1] - a[1])
  • convex hull
    • 수많은 점들이 있을 때 그중 일부를 이용해 볼록 다각형을 만들되 볼록 다각형 내에 모든 점이 있는 것을 만드는 알고리즘
    • 그라함 알고리즘이 대표적인 알고리즘
  • 그라함 알고리즘
    • O(NlogN)으로 처리가 가능
    • 방법 https://red-pulse.tistory.com/182
  • https://www.acmicpc.net/problem/1708
 

1708번: 볼록 껍질

첫째 줄에 점의 개수 N(3 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에 걸쳐 각 점의 x좌표와 y좌표가 빈 칸을 사이에 두고 주어진다. 주어지는 모든 점의 좌표는 다르다. x좌표와 y좌표의 범

www.acmicpc.net

import sys
import math

def input():
    return sys.stdin.readline().rstrip()

INF = 10e9

N = int(input())
P = [list(map(int, input().split())) for i in range(N)]
S = []

def incl(a, b):
    return INF if a[0] == b[0] else (a[1]-b[1])/(a[0]-b[0])

def dist(a, b):
    return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2

def ccw(a, b, c):
    return (b[0] - a[0])*(c[1] - a[1])-(c[0] - a[0])*(b[1] - a[1]) > 0

def convex_hull():
    for p3 in P:
        while len(S) >= 2:
            p1, p2 = S[-2], S[-1]
            if ccw(p1, p2, p3):
                break
            S.pop()
        S.append(p3)

    return len(S)

P.sort()
P = P[:1] + sorted(P[1:], key = lambda x: incl(x, P[0]))

print(convex_hull())

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

 

17403번: 가장 높고 넓은 성

첫 번째 줄에 n개의 정수 x1, x2, ..., xn을 공백으로 구분하여 출력한다. xi는 i 번째 표지판이 사용되었을 경우 사용된 층수이며, 사용되지 않았으면 0이다.

www.acmicpc.net

import sys
import math

def input():
    return sys.stdin.readline().rstrip()

INF = 10e9

N = int(input())
P = [list(map(int, input().split())) for i in range(N)]
ans = [0] * N

def incl(a, b):
    return INF if a[0] == b[0] else (a[1]-b[1])/(a[0]-b[0])

def dist(a, b):
    return (a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2

def ccw(a, b, c):
    return (b[0] - a[0])*(c[1] - a[1])-(c[0] - a[0])*(b[1] - a[1])

def convex_hull(prev_P, cur):
    S = []
    sorted_P = sorted(prev_P)
    sorted_P = sorted_P[:1] + sorted(sorted_P[1:], key = lambda x: (incl(x, sorted_P[0]), dist(x, sorted_P[0])))
    for p3 in sorted_P:
        while len(S) >= 2:
            p1, p2 = S[-2], S[-1]
            if ccw(p1, p2, p3) > 0:
                break
            S.pop()
        S.append(p3)
    if len(S) <= 2:
        return sorted_P, S
    ans[P.index(S[0])] = cur
    sorted_P.remove(S[0])
    
    for i in range(2, len(S)):
        if ccw(S[i-2], S[i-1], S[i]) != 0:
            ans[P.index(S[i-1])] = cur
        sorted_P.remove(S[i-1])
        
    ans[P.index(S[-1])] = cur
    sorted_P.remove(S[-1])
    
    return sorted_P, S

prev_P = P.copy()

cur = 1
while True:
    prev_P, k = convex_hull(prev_P, cur)
    if len(k) <= 2:
        break
    cur += 1
print(*ans)

 
 

+ Recent posts