주어진 점들 중 최대 맨해튼 거리(Manhattan Distance)를 빠르게 찾는 방법
https://atcoder.jp/contests/abc178/tasks/abc178_e
E - Dist Max
AtCoder is a programming contest site for anyone from beginners to experts. We hold weekly programming contests online.
atcoder.jp
n개의 점이 주어질때, 이들 쌍으로 만들 수 있는 가장 긴 맨해튼 거리는?
n이 최대 20만이기 때문에 $O(N^2)$으로 직접 비교할 수는 없다
두 점 (xi,yi), (xj,yj)에 대하여 맨해튼 거리는 |xi - xj| + |yi - yj| = A
A는 xi,xj, yi,yj 사이 대소관계에 따라 다음과 같이 풀어낼 수 있다
1) $x_{i} >= x_{j}$이고 $y_{i} >= y_{j}$이면
$x_{i} - x_{j} + y_{i} - y_{j} = x_{i} + y_{i} - (x_{j} + y_{j})$
2) $x_{i} >= x_{j}$ 이고 $y_{i} < y_{j}$ 이면
$x_{i} - x_{j} - (y_{i} - y_{j}) = x_{i} - y_{i} - (x_{j} - y_{j})$
3) $x_{i} < x_{j}$ 이고 $y_{i} >= y_{j}$ 이면
$- (x_{i} - x_{j}) + (y_{i} - y_{j}) = - (x_{i} - y_{i}) + (x_{j} - y_{j})$
4) $x_{i} < x_{j}$ 이고 $y_{i} < y_{j}$ 이면
$- (x_{i} - x_{j}) - (y_{i} - y_{j}) = - (x_{i} + y_{i}) + (x_{j} + y_{j})$
항상 양수가 되도록 절댓값을 제거한 것이므로 4가지 모두 양수이다.
여기서 핵심은 필요한 것은 (xi+yi), (xi-yi), (xj+yj), (xj-yj) 4가지이다.
따라서 (xi+yi)와 (xi-yi)를 각각 O(N)에 구한 다음
1) (xi+yi)의 최댓값 - (xi+yi)의 최솟값
2) (xi-yi)의 최댓값 - (xi-yi)의 최솟값
중 더 큰 값을 구하면 될 것이다.
n = int(input())
A = []
B = []
for _ in range(n):
x,y = map(int,input().split())
A.append(x+y)
B.append(x-y)
A.sort()
B.sort()
print(max((A[-1] - A[0]), (B[-1] - B[0])))
참고로 모든 실수 a,b에 대해 $|a| + |b| = max(|a+b|, |a-b|)$이다.
왜냐하면 |a| = max(a,-a)이므로
$|a| + |b| = max(a,-a) + max(b,-b) = max(a+b,-(a+b), -(a-b), a-b) = max(|a+b|, |a-b|)$
<똑같은 문제>
'알고리즘 > 애드 혹 알고리즘' 카테고리의 다른 글
m개의 원소를 조건에 맞게 n개의 원소에 배치하는 방법 (0) | 2024.12.02 |
---|---|
논리식의 일부를 바꿔서 원하는 결과가 나오게 만드는 방법 (0) | 2024.09.23 |
a b k d e g h i l m n ng o p r s t u w y 순서로 정렬하기? (0) | 2024.09.14 |
문자열 수를 10진법으로 바꾸는 테크닉2 - n을 n번 이어붙인 정수 (0) | 2024.09.08 |
맨 위 정수가 주어질때, 아래 두 수의 합이 위 정수가 되는 피라미드 만들기 (0) | 2024.09.06 |