Week 01 ~ 04 : 알고리즘 문제 풀이

파이썬 백준 2470 두 용액

정글러 2021. 11. 11. 18:38
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

양 끝을 기준으로 잡고 조건에 따라 왼쪽 끝을 옮길지 오른쪽 끝을 옮길지 결정

 

비슷한것같으면서도 이게 같냐 생각해보면 같다는 생각은 안드는데...