반응형

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

 

4181번: Convex Hull

때때로 주어진 점들 사이에서 볼록 껍질(Convex Hull)을 찾아내는 기술은 요긴하게 쓰인다. ACM 월드파이널에서 볼록 껍질을 응용해야 하는 문제가 출제되다 보니, 이걸 할 줄 아는 것은 참가자의 소

www.acmicpc.net

 

 

가지 주의할 점이 있었는데, 이미 볼록 껍질을 찾아낸 좌표가 주어지므로 'Y'로 표시된 좌표는 모두 볼록 껍질에 들어가야만 했습니다. 그래서 변 내에 좌표가 포함된 상황에도 그것을 포함시켜주어야 했습니다.

발견하지 못하던 예외 케이스가 있었는데, 기준점에서 시계 반대 방향으로 정렬할 때, ccw가 0이라면(우상단 대각선) y가 더 큰 좌표가 먼저 선택되어야 볼록 껍질에 포함시킬 수 있었습니다.

 
 
#include <iostream>
#include <algorithm>
#include <vector>
typedef long long ll;
using namespace std;

int n;
ll x, y;
char c;
vector<pair<ll, ll>> pos, hull, res;

// 시계 음수, 반시계 양수, 일직선 0
ll ccw(ll x1, ll y1, ll x2, ll y2, ll x3, ll y3) {
	return (x1 * y2 + x2 * y3 + x3 * y1) - (y1 * x2 + y2 * x3 + y3 * x1);
}

bool compAscXAscY(pair<ll, ll>& a, pair<ll, ll>& b) {
	if (a.first == b.first) return a.second < b.second;
	else return a.first < b.first;
}

bool comp(pair<ll, ll>& a, pair<ll, ll>& b) {
	ll res = ccw(pos[0].first, pos[0].second, a.first, a.second, b.first, b.second);
	if (res == 0) {
		if (a.first == b.first) return a.second > b.second;
		else {
			if (a.second == b.second) return a.first < b.first;
			else return a.second > b.second; // 우상단 대각선일 때, 우상단에 있는 좌표를 먼저 오게 함
		}
	}
	else {
		// 기준점, a, b가 반시계 방향을 이루도록 정렬
		return res > 0;
	}
}

int main() {
	scanf("%d", &n);
	for (int i = 0; i < n; i++) {
		scanf("%lld %lld %c", &x, &y, &c);
		if (c == 'Y') pos.push_back({ x, y });
	}

	sort(pos.begin(), pos.end(), compAscXAscY);
	sort(pos.begin() + 1, pos.end(), comp);

	hull.push_back(pos[0]);
	hull.push_back(pos[1]);

	for (int i = 2; i < pos.size(); i++) {
		while (hull.size() >= 2) {
			pair<ll, ll> a = hull.back();
			hull.pop_back();
			pair<ll, ll> b = hull.back();
			ll res = ccw(pos[i].first, pos[i].second, a.first, a.second, b.first, b.second);
			if (res <= 0) {
				hull.push_back(a);
				break;
			}
		}
		hull.push_back(pos[i]);
	}

	printf("%d\n", hull.size());
	for (int i = 0; i < hull.size(); i++) {
		printf("%lld %lld\n", hull[i].first, hull[i].second);
	}
}
반응형

'Algorithm' 카테고리의 다른 글

백준 2836 : 수상 택시  (0) 2021.11.19
백준 2023 : 신기한 소수  (0) 2021.11.19
백준 2699 : 격자점 컨벡스헐  (0) 2021.11.18
백준 1310 : 달리기 코스  (0) 2021.11.18
백준 6439 : 교차  (0) 2021.11.18

+ Recent posts