"Convex Hull"의 두 판 사이의 차이
DnlzkWiki
Dipolemoment (토론 | 기여) |
|||
(다른 사용자 한 명의 중간 판 하나는 보이지 않습니다) | |||
1번째 줄: | 1번째 줄: | ||
Convex Hull(볼록 껍질)은 주어진 모든 | Convex Hull(볼록 껍질)은 주어진 모든 [[점]]을 포함하는 가장 작은 [[볼록다각형]]이다. | ||
== Graham Scan == | == Graham Scan == | ||
18번째 줄: | 18번째 줄: | ||
#상,하부에 겹치는 점들이 있으므로 그들을 제외 시키고 스택을 합친다. | #상,하부에 겹치는 점들이 있으므로 그들을 제외 시키고 스택을 합친다. | ||
합쳐진 스택이 ConvexHull이다.<br> | 합쳐진 스택이 ConvexHull이다.<br> | ||
boj 4181번 풀이이다.([[코드]] 작성자가 코딩을 못해서 코드가 이상할 수도 있다..) | |||
<syntaxhighlight lang="python" line="1"> | <syntaxhighlight lang="python" line="1"> | ||
import sys | import sys | ||
46번째 줄: | 47번째 줄: | ||
for l in dots: | for l in dots: | ||
print(l[0],l[1]) | print(l[0],l[1]) | ||
</syntaxhighlight> |
2023년 8월 24일 (목) 09:46 기준 최신판
Convex Hull(볼록 껍질)은 주어진 모든 점을 포함하는 가장 작은 볼록다각형이다.
Graham Scan
- 기준점을 잡는다. (보통 y좌표가 가장 작은 점을 기준으로 한다)
- 기준점으로 하여 다른 점들을 반시계 방향으로 정렬한다.
- 첫 번째와 두 번째 정점을 스택에 넣고 시작한다.
- 스택에서 second와 first를 순서대로 꺼내고 next값과 ccw를 하여 > 0인지 확인한다. (좌회전 하는지 확인)
- 좌회전한다면 볼록 껍질이 될 수 있다는 의미이고 pop했던 second를 다시 스택에 넣어 주고 next도 스택에 넣어 준다.
- 우회전한다면 second 점은 버리고 first를 스택에 넣는다.
- 4번 과정을 next값이 없을 때까지 반복한다.
스택에 남아 있는 점들이 Convex Hull이다.
MonotoneChain
- Convex Hull을 상부와 하부로 나눈다.
- 점들은 먼저 정렬한 이후 Graham Scan과정과 같이 ccw를 사용하여 스택에 넣어준다.
- 하부는 상부 배열을 뒤집어 위 과정을 수행해준다.
- 상,하부에 겹치는 점들이 있으므로 그들을 제외 시키고 스택을 합친다.
합쳐진 스택이 ConvexHull이다.
boj 4181번 풀이이다.(코드 작성자가 코딩을 못해서 코드가 이상할 수도 있다..)
import sys
input=sys.stdin.readline
def ccw(p1,p2,p3):
return p1[0]*(p2[1] - p3[1]) + p2[0]*(p3[1] - p1[1]) + p3[0]*(p1[1] - p2[1])
def monotone(points):
points.sort()
lower=[]
upper=[]
for i in points:
while len(lower) > 1 and ccw(lower[-2],lower[-1],i) < 0:
lower.pop()
lower.append(i)
for j in reversed(points):
while len(upper) > 1 and ccw(upper[-2],upper[-1],j) < 0:
upper.pop()
upper.append(j)
return lower[:-1]+upper[:-1]
dots=[]
n=int(input())
for k in range(n):
x,y,c = input().split()
if c == 'Y':
dots.append([int(x),int(y)])
dots=monotone(dots)
print(len(dots))
for l in dots:
print(l[0],l[1])