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

 

이번에 볼 문제는 백준 27297번 문제인 맨해튼에서의 모임이다.
문제는 아래 링크를 확인하자.

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

 

27297번: 맨해튼에서의 모임

첫 번째 줄에 점의 차원을 나타내는 정수 $N$과 점의 개수를 나타내는 정수 $M$ ($1 \le N, M \le 1\,000$)이 공백으로 구분되어 주어진다. 다음 $M$개의 줄에는 $i$번째 점의 좌표 $P_i = (P_{i,1}, P_{i,2}, \cdots,

www.acmicpc.net

N차원 점 M개와의 맨해튼거리의 총합이 가장 작은 점을 찾는 문제이다.

 

좌표의 i번째 성분과 j번째 성분은 i와 j가 다르다면 서로 맨해튼거리에 영향을 주지 않으므로, 각 성분별로 맨해튼거리의 총합을 최소화하는 위치를 찾아내는 것으로 문제를 해결할 수 있다.

 

찾는 점의 i번째 성분은 주어진 M개의 점의 i번째 성분의 중앙값(median)임을 이용해 문제를 해결해주자. 중앙값의 앞뒤로 i번째 성분의 값을 이동시키면서 그 때의 맨해튼 거리의 증감이 어떻게 되는지를 살펴보면 이 위치가 답임을 이해할 수 있을 것이다.

 

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

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

int N, M;
vector<ll> vec[1000];
ll D;
vector<ll> ans;

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

	cin >> N >> M;
	for (int m = 0; m < M; m++) {
		for (int i = 0; i < N; i++) {
			ll x; cin >> x;
			vec[i].emplace_back(x);
		}
	}

	for (int i = 0; i < N; i++) {
		sort(vec[i].begin(), vec[i].end());
		ans.emplace_back(vec[i][M / 2]);
		for (auto& x : vec[i]) D += abs(x - ans.back());
	}

	cout << D << '\n';
	for (auto& x : ans) cout << x << ' ';
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 24622 // C++] Blocks  (0) 2023.02.03
[BOJ 22937 // C++] 교수님 계산기가 고장났어요!  (0) 2023.02.03
[BOJ 9780 // C++] Range Sum Query  (0) 2023.02.02
[BOJ 27294 // C++] 몇개고?  (0) 2023.02.02
[BOJ 15841 // C++] Virus Outbreak  (0) 2023.02.02

+ Recent posts