# 그라함 알고리즘 # ccw(블록껍질) # calliper caliper
3개 개념을 모두 알아야 풀 수 있습니당...
# 실수 했던 점
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <set> #include <map> #define MAX 100005 #define INF 987654321 #define MOD 31991 #pragma warning(disable:4996) using namespace std; typedef long long ll; typedef pair<int, int> pi; typedef struct { ll x, y; }cood; int n; cood arr[200100]; // ccw(a, b, c) == 0 일직선, == 1 반시계, == -1 시계 int ccw(ll ax, ll ay, ll bx, ll by, ll cx, ll cy) { ll k = (ll)(bx - ax)*(cy - ay) - (ll)(cx - ax)*(by - ay); if (k > 0)return 1; if (k < 0)return -1; return 0; } int ccw(cood a, cood b, cood c) { return ccw(a.x, a.y, b.x, b.y, c.x, c.y); } ll get_dist(cood a, cood b) { return (b.x - a.x) * (b.x - a.x) + (b.y - a.y)*(b.y - a.y); } // 제일 작은 0번 좌표와 각 비교 -> convexhull용 정렬 bool cood_cmp(cood a, cood b) { int k = ccw(arr[0], a, b); if (!k)return abs(a.y - arr[0].y) + abs(a.x - arr[0].x) < abs(b.y - arr[0].y) + abs(b.x - arr[0].x); return k > 0; } void rotating_calipers() { scanf("%d", &n); for (int i = 0; i < n; i++) { scanf("%lld %lld", &arr[i].x, &arr[i].y); } // convex_hull for (int i = 0; i < n; i++) { if (arr[0].y > arr[i].y || arr[0].y == arr[i].y && arr[0].x > arr[i].x) { swap(arr[0], arr[i]); } } sort(arr + 1, arr + n, cood_cmp); vector<int> convex_hull = { 0 }; for (int i = 1; i < n; i++) { while (convex_hull.size() > 1 && ccw(arr[convex_hull[convex_hull.size() - 2]], arr[convex_hull[convex_hull.size() - 1]], arr[i]) <= 0) convex_hull.pop_back(); convex_hull.push_back(i); } //rotating calipers int j = 1, m = convex_hull.size(); ll ans = 0; cood p = arr[0], q = arr[1]; for (int i = 0; i < m; i++) { int ni = (i + 1) % m; while (true) { int nj = (j + 1) % m; int v = ccw(0, 0, arr[convex_hull[ni]].x - arr[convex_hull[i]].x, arr[convex_hull[ni]].y - arr[convex_hull[i]].y, arr[convex_hull[nj]].x - arr[convex_hull[j]].x, arr[convex_hull[nj]].y - arr[convex_hull[j]].y); if (v > 0) j = nj; else break; } ll v = get_dist(arr[convex_hull[i]], arr[convex_hull[j]]); if (ans < v) { ans = v; p = arr[convex_hull[i]]; q = arr[convex_hull[j]]; } } // ans -> 제일 긴 길이, p, q 그 좌표값 double a = (double)(p.x - q.x), b = (double)(p.y - q.y); printf("%lf\n", sqrt(a*a+b*b)); } int main() { rotating_calipers(); return 0; }
'IT > BOJ' 카테고리의 다른 글
백준(BOJ) 11585 속타는 저녘 메뉴 ** (0) | 2018.09.30 |
---|---|
백준(BOJ) 1298 노트북 주인을 찾아서 ** (0) | 2018.09.30 |
백준(BOJ) 1965 상자넣기 * (0) | 2018.09.28 |
백준(BOJ) 1275 커피숍2 ** (0) | 2018.09.28 |
백준(BOJ) 2042 구간 합 구하기 ** (0) | 2018.09.17 |