본문 바로가기

Algorithm7

볼록껍질 (Convexhull) 구하기 계산기하 문제에서 CCW와 더불어 가장 많이 쓰이는 볼록껍질을 구하는 알고리즘을 소개한다. 볼록껍질(convexhull) 이란, 내각이 모두 180도 미만이면서 N개의 점들을 모두 포함하는 다각형을 의미한다. N개의 점들이 주어졌을 때 우리는 O(n log n) 만에 볼록껍질을 구성하는 점들을 찾을 수 있다. 다른 블로그들에서 각도 순으로 정렬하여 찾는 Graham Scan 알고리즘을 소개하므로, 여기서는 원리는 비슷하지만 조금 다르게 구현하는 알고리즘을 소개한다. 우선 이 문제는 정렬이 매우 쉽다. 각도 기준이 아닌, 단순하게 x 좌표를 기준으로 오름차순으로 정렬하고 시작한다. 이제 우리는 CCW를 이용하여 오른쪽 점들만 계속해서 선택할 것이다. 아래 그림을 보자. x 좌표 정렬 후 1번과 2번을 잇는.. 2022. 8. 31.
Mo's Algorithm BOJ 13547 문제를 기준으로 이 알고리즘을 설명하려고 한다.이 문제는 [L, R] 쿼리가 입력되면, A[L], A[L+1], ..., A[R] 중 서로 다른 수의 개수를 출력하는 것이다. Naive 한 풀이는 매우 쉬운데, 조금 덜 Naive 하게 생각해보자.즉, 이전 쿼리에 대한 답을 알고 있다는 가정 하에, 현재 쿼리는 그 변화량만 계산해서 더해주면 된다. 이전 쿼리의 L, R 을 한 칸씩 움직이면서 현재 쿼리의 L, R 쿼리로 만들어준다.이 때 숫자가 제거되거나 추가될텐데, 그에 맞게 답을 조정하는 간단한 방식이다. 하지만 이 방법 또한 O(NQ) 로 TLE가 날 것이다.Mo's Algorithm 은 오프라인 쿼리로, 이 방법을 그대로 적용하지만, 쿼리의 순서만 바꾸는 것이다.재미있는 점은,.. 2022. 8. 29.
Set 와 PBDS 우리가 흔히 쓰는 std::set 은, 특정값보다 작은 원소를 세거나, K번째 원소를 구하는 작업을 O(log N) 만에 할 수 없다. 하지만, PBDS (Policy Based Data Structure) 를 활용하면 가능하다. 물론, Set 을 안 쓰고도 할 수 있다. 특정값보다 작은 원소 개수는 세그먼트 트리로 알 수 있으며, K번째 원소를 구하는 것은 세그먼트 트리 + 이분탐색으로 해결할 수 있다. 입력된 숫자 범위가 크더라도 좌표압축을 하거나, 동적 세그먼트 트리를 쓰면 될 것이다. 하지만, 위 기능들이 제공되는 Set 을 사용하면 훨씬 간단할 것이다. #include #include using namespace __gnu_pbds; #define ordered_set tree 우선 위 코드를 .. 2022. 8. 25.
CCW 에 대하여 계산기하의 기본 중의 기본이라고 할 수 있는 CCW 에 대해 알아보고자 한다. CCW는 Counter ClockWise (반시계) 의 줄임말으로, 점 3개에 대한 방향성 관계를 알 수 있는 수치다. 그림으로 보면, 세 점 A, B, C 가 2차원 좌표평면에 있다고 하자. 반직선 AB 에 대하여 점 C가 왼쪽에 있는지, 일직선 상에 있는지, 오른쪽에 있는지 어떻게 알 수 있을까? 간단한 선형대수학 내용을 알아보자. 위처럼 2×2 행렬 A가 있다고 해보자. 이 행렬 A의 행렬식 det(A) 는 아래와 같이 정의된다. det(A) 도 되고 |A| 도 맞는 표현이다. 두 대각선 원소들의 곱을 빼면 det(A)가 되는 것이다. ad < bc 라면 det(A)는 얼마든지 음수가 될 수 있다. 그렇다면, 3×3 행렬.. 2022. 8. 25.
Trie 자료구조 길이 L 짜리 문자열이 N개 담긴 list 에서 특정 문자열을 검색하는 시간복잡도가 어떻게될까? 이진탐색을 쓴다면 O(log N) 처럼 보이지만, 두 문자열을 비교하는 strcmp 함수의 시간복잡도가 O(L) 이기에, 전체 시간복잡도는 O(L log N) 이 된다. 심지어 list 가 정렬되어 있어야 한다. Trie 를 쓴다면, O(NL) 의 시간복잡도로 전처리를 하게 된다. 이후에는 어떤 문자열이 오더라도 O(L) 만에 list 에서 검색이 가능하다. BOJ 5670 휴대폰 자판을 예시로 들어보자. hell, hello, heaven, goodbye 4개의 문자열이 들어온다. hell 이 먼저 들어오니까 이 때의 Trie 를 그림으로 확인해보자. 0. 초기 상태 Trie의 초기 상태. 루트 노드만 존재.. 2022. 8. 24.
KMP 알고리즘 : 문자열 검색 문자열을 검색하는 KMP 알고리즘은 Failure Function 에 대한 이해가 필수다. Failure Function 길이 N 짜리 문자열에서 길이 M의 문자열을 검색하는 작업을 O(N+M)에 하는 KMP 알고리즘을 이해하려면, 우선 Failure Function (실패 함수) 를 이해해야 한다. 이 글에서는 Failure Function 에 관한 내용만 daisylum.tistory.com 들어가기 전에, Failure Function 을 포함하여 이 글은 1-based index 를 기반으로 한다. 즉 모든 문자열은 배열의 1번 인덱스부터 담겨 있다고 가정한다. 문제 상황은 다음과 같다. 문자열 Str 에서 문자열 Want 가 나타나는 위치를 모두 파악할 수 있을까? Str 의 길이를 S, Wan.. 2022. 8. 19.