Loading [MathJax]/jax/output/CommonHTML/jax.js
 

주어진 점들 중 최대 맨해튼 거리(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(N2)으로 직접 비교할 수는 없다

 

두 점 (xi,yi), (xj,yj)에 대하여 맨해튼 거리는 |xi - xj| + |yi - yj| = A

 

A는 xi,xj, yi,yj 사이 대소관계에 따라 다음과 같이 풀어낼 수 있다

 

1) xi>=xj이고 yi>=yj이면

 

xixj+yiyj=xi+yi(xj+yj)

 

2) xi>=xj 이고 yi<yj 이면

 

xixj(yiyj)=xiyi(xjyj)

 

3) xi<xj 이고 yi>=yj 이면

 

(xixj)+(yiyj)=(xiyi)+(xjyj)

 

4) xi<xj  이고 yi<yj 이면

 

(xixj)(yiyj)=(xi+yi)+(xj+yj)

 

항상 양수가 되도록 절댓값을 제거한 것이므로 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|,|ab|)이다.

 

왜냐하면 |a| = max(a,-a)이므로

 

|a|+|b|=max(a,a)+max(b,b)=max(a+b,(a+b),(ab),ab)=max(|a+b|,|ab|)

 

 

<똑같은 문제>

 

 

2381번: 최대 거리

 

728x90