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

 

이번에 볼 문제는 백준 16210번 문제인 DSHS Bank이다.
문제는 아래 링크를 확인하자.

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

 

16210번: DSHS Bank

본점이 되어야 할, 즉 다른 지점들과의 택시 거리의 합이 가장 작은(그런 정점이 여러 개이면 가장 번호가 작은) 지점의 번호를 나타내는 정수 하나를 출력한다. 지점의 번호가 1번부터 시작함에

www.acmicpc.net

다른 모든 점에서 어느 한 점 (X,Y)까지의 거리의 총합은 (X - 왼쪽에 있는 점 X좌표)들과 (오른쪽에 있는 점 x좌표 - X)들, 그리고 (Y - 아래쪽에 있는 점 Y좌표)들과 (위쪽에 있는 점 Y좌표들 - Y)들의 합으로 구할 수 있다.

 

위의 계산에 필요한 점의 개수 및 X좌표 또는 Y좌표의 값의 총합은 정렬 후 O(점의 개수)에 전처리가 가능하므로, 이를 이용하여 각 점으로의 거리의 총합을 계산해내 그중 최솟값을 찾아 문제를 해결하자.

 

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

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

int N;
ll xtotalL, xtotalR, ytotalL, ytotalR;
pair<ll, int> xp[500000], yp[500000];

ll dist[500000];
ll mn = 1000000000000000007LL, ans;

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

	cin >> N;
	for (int i = 0; i < N; i++) {
		ll X, Y; cin >> X >> Y;
		xtotalR += X, ytotalR += Y;
		xp[i] = make_pair(X, i), yp[i] = make_pair(Y, i);
	}

	sort(xp, xp + N), sort(yp, yp + N);
	for (int i = 0; i < N; i++) {
		xtotalL += xp[i].first, xtotalR -= xp[i].first;
		dist[xp[i].second] += (xp[i].first * (i + 1) - xtotalL) + (xtotalR - xp[i].first * (N - i - 1));
	}
	for (int i = 0; i < N; i++) {
		ytotalL += yp[i].first, ytotalR -= yp[i].first;
		dist[yp[i].second] += (yp[i].first * (i + 1) - ytotalL) + (ytotalR - yp[i].first * (N - i - 1));
	}

	for (int i = 0; i < N; i++) {
		if (dist[i] < mn) mn = dist[i], ans = i;
	}

	cout << ans + 1;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 16206 // C++] 롤케이크  (0) 2023.09.15
[BOJ 16207 // C++] 직사각형  (0) 2023.09.14
[BOJ 16209 // C++] 수열 섞기  (0) 2023.09.12
[BOJ 25367 // C++] 너무 시시했다  (0) 2023.09.11
[BOJ 11946 // C++] ACM-ICPC  (0) 2023.09.10

+ Recent posts