ccw 알고리즘(?)을 이용하여 블록 껍질(convex hull)을 뽑아내는 알고리즘 입니다.
시간복잡도는 O(nlogn)
# 풀이 순서
1. 가장 x, y가 작은 ori점을 찾는다.
2. ori 이외의 점들을 반시계 방향을 정렬한다.
3. ccw를 활용하여 블록 껍질을 찾는다.
ccw>0이 되었을 때만 스택에 넣어주면 된다.
# 관련문제 : https://www.acmicpc.net/problem/1708
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #define MAX 200005 #define INF 987654321 #define MOD 31991 #pragma warning(disable:4996) using namespace std; typedef long long ll; typedef pair<int, int> pi; struct st{ int x,y; int p,q; st() : x(0),y(0),p(0),q(0){} st(int x1, int y1): x(x1),y(y1),p(0),q(0){} }s[MAX]; // x, y : 원래 좌표 p, q : 기준점에 대한 좌표 bool cmp(const st &a,const st &b) { if (1LL * a.q * b.p != 1LL * a.p*b.q) return 1LL * a.q * b.p < 1LL * a.p*b.q; // 기준점을 (0,0)이라 했을때 ccw라 생각하면 된다. if (a.y != b.y) return a.y < b.y; return a.x < b.x; } // a, b에 대한 좌표 정렬 하기 위한 함수 ll ccw(const st &a,const st &b,const st &c) { return 1LL * (a.x * (b.y-c.y) + b.x*(c.y-a.y) + c.x*(a.y-b.y)); } // ccw 함수 int t,n; vector<int> v; int main() { scanf("%d",&n); for(int i=0;i<n;i++) { int x,y; scanf("%d%d",&x,&y); s[i]=st(x,y); } sort(s,s+n,cmp); // 가장 작은 x,y(ori)를 가지는 좌표를 찾는다. for(int i=1;i<n;i++) { s[i].p=s[i].x-s[0].x; s[i].q=s[i].y-s[0].y; } sort(s+1,s+n,cmp); // ori를 기준으로 다른 좌표들을 반시계 방향으로 정렬한다. v.push_back(0); v.push_back(1); // 최초 2개의 점을 넣는다. int next = 2; // 다음 넣을 점 while (next < n) // convex hull 만들기 { while (v.size() >= 2) { int first, second; second = v.back(); v.pop_back(); first = v.back(); if (ccw(s[first], s[second], s[next]) > 0) // 바로 이전 2개의 점과 새로운 다음 점이 반 시계방향이라면 넣는다. { v.push_back(second); break; } } v.push_back(next++); // 다음 점을 넣는다. } printf("%d",v.size()); // 블록의 껍질 개수를 출력한다. return 0; }
'IT > 알고리즘 및 자료구조' 카테고리의 다른 글
[알고리즘 정리] 세그먼트 트리 (0) | 2018.09.17 |
---|---|
[알고리즘 정리] 이분 탐색 (0) | 2018.09.14 |
[알고리즘] 구조체를 이용한 행렬의 곱 구현 (0) | 2018.08.11 |
[알고리즘 정리] 최장 증가 수열(LIS,Largest Increasing Sequence) 알고리즘 (2) | 2018.07.16 |
[알고리즘 정리] 최소 신장 트리(MST, Minumum Spanning Tree) 알고리즘(프림 알고리즘) (0) | 2018.06.03 |