※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 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 |