import sys
sys.setrecursionlimit(10**8)
input = sys.stdin.readline
n = int(input())
L = list(map(int, input().split()))
L.sort()
al = 0
ar = n- 1
amin = abs(L[al] + L[ar])
def Bsearch(l, pl, pr) :
global amin, al, ar
if pl >= pr :
return [amin, al, ar]
sum = l[pl] + l[pr]
if abs(sum) < amin :
amin = abs(sum)
al = pl
ar = pr
if sum == 0 :
return [amin, al, ar]
if sum > 0 :
return Bsearch(l, pl, pr - 1)
else :
return Bsearch(l, pl + 1, pr)
ans = Bsearch(L, al, ar)
print(L[ans[1]], L[ans[2]])
|
인풋받은 list를 정렬하고, 왼쪽 오른쪽 커서와 min값의 초기값을 설정한다.
둘의 합이 양수면 합을 낮추기 위해 양수쪽 커서를 한 칸 아래로 보내 재귀한다.
둘의 합의 음수면 합을 높이기 위해 음수쪽 커서를 한 칸 아래로 보내 재귀한다.
이 과정에서 min값을 계속 갱신하고, 합이 0인 경우가 발견되거나 두 커서가 만나면 탐색을 종료한다.
이분탐색이라면 지금까지 풀었던 두 문제처처럼 range를 center로 반으로 잘라 재귀하는 방식을 떠올렸는데,
이렇게 양 끝에서부터 좁혀가는 방식도 이분의 일종인가 보다.
중간에 기준을 잡고 조건에 따라 왼쪽으로 옮길지 오른쪽으로 옮길지 결정
vs
양 끝을 기준으로 잡고 조건에 따라 왼쪽 끝을 옮길지 오른쪽 끝을 옮길지 결정
비슷한것같으면서도 이게 같냐 생각해보면 같다는 생각은 안드는데...
'Week 01 ~ 04 : 알고리즘 문제 풀이' 카테고리의 다른 글
파이썬 백준 2630 색종이 만들기 (0) | 2021.11.12 |
---|---|
파이썬 백준 8983 사냥꾼 (0) | 2021.11.12 |
파이썬 백준 2805 나무 자르기 (0) | 2021.11.11 |
파이썬 백준 1920 수 찾기 (0) | 2021.11.11 |
파이썬 백준 2503 숫자 야구 (0) | 2021.11.11 |