1. 모든 점까지 맨해튼 거리의 합이 최소가 되는 점의 위치?
m차원의 n개의 점들 P1(x11,x12,...,x1m),...Pn(xn1,xn2,...,xnm)에 대하여,
이들까지 맨해튼 거리의 합이 최소가 되는 점 X의 좌표를 구하라고 한다면, 어떻게 구할 수 있을까?
정답은 n개의 점들을 1,2,...,m차원의 좌표 값에 대하여 정렬한 다음, 중앙값에 해당하는 점의 좌표 Pmedian이 된다.
직관적으로 쉽게 눈치챌 수 있기는 한데, 왜 그런지 생각해보자.
2. 증명
먼저 점들의 좌표가 합에 서로 영향을 주지 않는다는 점을 관찰하자.
예를 들어 (3,5), (4,2), (5,1)에 대하여 (x,y)까지 맨해튼 거리의 합은..
|x−3|+|y−5|+|x−4|+|y−2|+|x−5|+|y−1|=|x−3|+|x−4|+|x−5|+|y−5|+|y−2|+|y−1|
즉 맨해튼 거리의 합은 각 차원의 좌표 합끼리 나눌 수 있다.
(x1,y1),(x2,y2),...,(xn,yn)에 대하여..
S=n∑i=1|x−xi|+n∑i=1|y−yi|
그러므로 하나의 차원에 대해 최솟값을 생각한다면, 나머지 차원에 대해서도 동일하게 생각할 수 있다.
즉, 이제 문제는 f(x)=∑ni=1|x−xi|가 최소가 되는 x는 무엇인가?
마찬가지로 합이 서로 영향을 주지 않기 때문에 일반성을 잃지 않고 x1<x2<...<xn으로 정렬된 상태를 가정할 수 있다.
정렬한 상태에서 어떤 m에 대하여, xm≤x<xm+1이 성립하는 x에 대하여...
x1,x2,x3,...,xm는 x보다 작거나 같으므로 |x−xi|=x−xi
xm+1,xm+2,...,xn은 x보다 크므로, |x−xi|=xi−x
그러므로, f(x)=m∑i=1(x−xi)+n∑i=m+1(xi−x)
식을 계산해보면... f(x)=mx−(nx−mx)+n∑i=m+1xi−m∑i=1xi=(2m−n)x+n∑i=m+1xi−m∑i=1xi
x에 대해 미분하면, f'(x) = 2m-n이다.
그러므로, f'(x) > 0인 2m > n이면 f(x)가 증가하고 f'(x) < 0인 2m < n이면 f(x)가 감소하고 n = 2m에서 극값을 가진다.
이 말이 무슨말일까?
m < n/2이면, f(x)가 감소하다가 m = n/2에서 극값을 가지고 m > n/2이면 f(x)가 증가하는 형태이다.
즉, m = n/2에서 f(x)가 최솟값을 가진다.
구체적으로 n = 2m-1이라고 하자.
n = 1 >>> m = 1
n = 3 >>> m = 2
n = 5 >>> m = 3
n = 7 >>> m = 4
...
예를 들어 n = 7인 경우 n/2 = 3.5인데, m으로 3.5보다 작은 값 m = 3을 고른다면, x3≤x<x4인 x에 대해서는 f(x)가 감소한다.
하지만 m > 3.5보다 큰 m = 4를 고르면 x4≤x<x5의 x에 대해서는 f(x)가 증가한다.
그러므로 x=x4에서 f(x)가 최솟값을 가진다고 이해할 수 있다.
이번엔 n = 2m으로 짝수라고 해보자.
n = 2 >> m = 1
n = 4 >> m = 2
n = 6 >> m = 3
n = 8 >> m = 4
...
예를 들어 n = 8인 경우 n/2 = 4인데, m으로 4보다 작은 값 m = 3에 대하여... x3≤x<x4인 x에 대해서는 f(x)가 감소한다.
그러다가 m = 4를 고르면 x4≤x<x5인 x에 대해서 f(x)가 0이 된다.
그리고 m = 5를 고르면 x5≤x<x6인 x에 대해서는 f(x)가 증가하기 시작한다.
그러므로 x4≤x<x5인 모든 x에 대하여 f(x)가 최소가 된다.
즉 n = 2m-1로 홀수이면 xm으로 유일한 점이 존재하지만,
n = 2m으로 짝수이면 xm≤x<xm+1인 모든 x에 대해 최소가 될 수 있다.
3. 연습문제1
14400번: 편의점 2
영선이는 이번에 편의점으로 창업을 하려고 계획 중이다. 이번 창업을 위해 많은 준비를 하고 있는데, 아직 편의점을 세울 위치를 결정을 하지 못했다. 영선이는 미리 시장조사를 하여, 주요 고
www.acmicpc.net
4. 풀이
n이 10만이라 위의 사실을 모르면 단순하게 풀기 어렵다..
위 알고리즘에 따라 x,y좌표 각각 x_points, y_points 배열 각각에 좌표들을 모아둔다.
x_points, y_points를 모두 정렬한다.
그리고 중앙에 있는 좌표 x_points[n//2], y_points[n//2]가 모든 맨해튼 거리의 합을 최소로 하는 점의 좌표이므로 이를 구한다.
x_points,y_points를 다시 순회하여 x_points[n//2], y_points[n//2]의 맨해튼 거리의 합을 구한다.
from sys import stdin
n = int(stdin.readline())
x_points = []
y_points = []
for _ in range(n):
x,y = map(int,stdin.readline().split())
x_points.append(x)
y_points.append(y)
x_points.sort()
y_points.sort()
x,y = x_points[n//2],y_points[n//2]
answer = 0
for i in range(n):
answer += abs(x_points[i] - x)
answer += abs(y_points[i] - y)
print(answer)
증명하다가 느낀게 n = 7이면 7//2 = 3인데... 위에서 보인거라면 x4에서 최소여야하는데??
라고 생각했는데...
배열은 제로 인덱스라서 x_points[3]이 x4잖어..
5. 연습문제2
27297번: 맨해튼에서의 모임 (acmicpc.net)
27297번: 맨해튼에서의 모임
첫 번째 줄에 점의 차원을 나타내는 정수 N과 점의 개수를 나타내는 정수 M (1≤N,M≤1000)이 공백으로 구분되어 주어진다. 다음 M개의 줄에는 i번째 점의 좌표 $P_i = (P_{i,1}, P_{i,2}, \cdots,
www.acmicpc.net
정답이 여러개일 경우 아무거나 하나만 출력하라고 나와있는데 위에서 보인대로,
점의 개수가 짝수일 경우 중앙의 점 xm, xm+1로 이은 선분 위의 모든 점 xm≤x<xm+1에 대해 답이 될 수 있기 때문이다.
6. 풀이
위의 문제는 2차원이지만 이번 문제는 n차원에서 모든 맨해튼 거리의 합이 최소가 되는 점의 좌표를 구하는 것이다.
마찬가지로 동일하게 각 차원마다 좌표 배열 points[0], points[1], ... , points[n-1]을 모두 모아둔다.
points를 순회해서 얻은 points[0], points[1],..., points[n-1]에 대하여...
points[i] = point라 하고 이들을 정렬한다.
point에는 m개의 점 좌표가 들어있으므로 중앙의 좌표는 point[m//2]이다.
실제 최소가 되는 점의 좌표를 구해야하므로 point[m//2]도 따로 저장해두고, 다시 point를 하나하나 순회해서
맨해튼 거리 합을 누적시켜준다.
from sys import stdin
n,m = map(int,stdin.readline().split())
points = [[] for _ in range(n)]
for _ in range(m):
p = list(map(int,stdin.readline().split()))
for i in range(n):
points[i].append(p[i])
fermat = []
answer = 0
for point in points:
point.sort()
fermat.append(point[m//2])
for p in point:
answer += abs(p - fermat[-1])
print(answer)
print(' '.join(map(str,fermat)))
'기하학' 카테고리의 다른 글
선분의 길이가 주어질때 볼록 다각형(conver polygon)이 될 조건 (0) | 2023.08.25 |
---|---|
정육면체가 쌓인 3차원 도형의 겉넓이를 구하는 방법 (0) | 2023.08.25 |
모든 좌표 쌍의 맨해튼 거리의 합을 효율적으로 구하는 방법 (0) | 2023.08.24 |
기하학의 사칙연산인 CCW(Counter-ClockWise) 알고리즘 배우기 (0) | 2023.08.05 |
기하학 알고리즘의 기본 - 두 벡터의 외적(cross product)에 대하여 (0) | 2023.08.05 |