※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 2244번 문제인 민코프스키 합이다.
문제는 아래 링크를 확인하자.

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

 

2244번: 민코프스키 합

첫째 줄에 두 다각형 A와 B의 꼭짓점 개수 N과 M이 주어진다. (3 ≤ N, M ≤ 1,000) 다음 N개의 줄에는 다각형 A를 이루는 꼭짓점의 좌표가, 그 다음 M개의 줄에는 다각형 B를 이루는 꼭짓점의 좌표가 주

www.acmicpc.net

두 볼록한(convex) 다각형 영역의 벡터합은 다시 볼록한 다각형 영역이 되고, 그 꼭짓점은 기존 다각형의 꼭짓점의 벡터합들로 구성된다.

 

이를 이용해, 가능한 N*M가지 꼭짓점 후보를 이용해 convex hull을 구하는 것으로 문제를 해결하자.

 

아래는 제출한 소스코드이다.

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

int N;
pll points[1000000];
pll pA[1000], pB[1000];
vector<pll> upperhull; // leftmost x의 lowermost y부터 rightmost x의 uppermost y까지
vector<pll> lowerhull;

int CCW(pll& A, pll& B, pll& C) {
	ll ccw = (B.first - A.first) * (C.second - A.second) - (B.second - A.second) * (C.first - A.first);
	if (ccw > 0) return 1;
	else if (ccw < 0) return -1;
	else return 0;
}

void andrew_algorithm() {
	sort(points, points + N);

	//upperhull
	for (int i = 0; i < N; i++) {
		auto& cur = points[i];
		int cursize = upperhull.size();
		while (cursize > 1) {
			auto& L = upperhull[cursize - 2], & M = upperhull[cursize - 1];
			if (CCW(L, M, cur) != -1) upperhull.pop_back(), cursize--;
			else break;
		}
		upperhull.emplace_back(cur);
	}

	//lowerhull
	for (int i = 0; i < N; i++) {
		auto& cur = points[i];
		int cursize = lowerhull.size();
		while (cursize > 1) {
			auto& L = lowerhull[cursize - 2], & M = lowerhull[cursize - 1];
			if (CCW(L, M, cur) != 1) lowerhull.pop_back(), cursize--;
			else break;
		}
		lowerhull.emplace_back(cur);
	}
}

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int X, Y; cin >> X >> Y;
	for (int i = 0; i < X; i++) cin >> pA[i].first >> pA[i].second;
	for (int j = 0; j < Y; j++) cin >> pB[j].first >> pB[j].second;

	for (int i = 0; i < X; i++) {
		for (int j = 0; j < Y; j++) {
			points[N++] = make_pair(pA[i].first + pB[j].first, pA[i].second + pB[j].second);
		}
	}

	andrew_algorithm();

	cout << upperhull.size() + lowerhull.size() - 2 << '\n';

	for (int i = 0; i < lowerhull.size() - 1; i++) cout << lowerhull[i].first << ' ' << lowerhull[i].second << '\n';
	for (int i = upperhull.size() - 1; i > 0; i--) cout << upperhull[i].first << ' ' << upperhull[i].second << '\n';
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 13245 // C++] Sum of digits  (0) 2023.05.24
[BOJ 13242 // C++] Harps and Tails  (0) 2023.05.23
[BOJ 10254 // C++] 고속도로  (0) 2023.05.21
[BOJ 9240 // C++] 로버트 후드  (0) 2023.05.20
[BOJ 1708 // C++] 볼록 껍질  (0) 2023.05.19

+ Recent posts