study/백준(BOJ)

[Python] 2470. 두 용액

bbooo 2023. 4. 19. 23:00
728x90

https://www.acmicpc.net/problem/2470

 

2470번: 두 용액

첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00

www.acmicpc.net

 

접근법

  • 작은 순서대로 정렬한 후 이분 탐색을 통해 가장 0에 가까운 수를 찾음
  • 현재 두 용액의 합이 기존의 최소값보다 작을 경우 더 0에 가까운 값이 있나 찾아야 함 → L += 1을 통해 합의 크기를 키움
  • 현재 두 용액의 합이 기존의 최소값보다 클 경우 더 작은 합을 찾아야 함 → R -=1 을 통해 합의 크기를 줄임
import sys
def input_func(N):
    arr = list((map(int,input().split())))
    arr.sort()
    return arr


def sum_func(arr):
    L = 0
    R = len(arr) - 1
    min = [sys.maxsize, L, R] # 두 용액합의 현재까지의 최소값, L idx, R idx

    while L < R:
        sum = arr[L] + arr[R]
        if sum == 0:
            min[1], min[2] = arr[L], arr[R]
            break
        if abs(sum) < abs(min[0]):
            min[0] = sum
            min[1] = arr[L]
            min[2] = arr[R]
        if sum < 0: # 최소값이 0보다 작음, abs[0]으로 업데이트 되지 않을 수 있으므로 현재 값들의 합 이용
            L += 1
        else: # 최소값이 0보다 크기 때문에
            R -= 1
    print(min[1], min[2])
    return


def main():
    N = int(input())
    arr = input_func(N)
    sum_func(arr)

if __name__=="__main__":
    main()


유의할 점 및 새로 배운 사항 

1. sys.maxsize 

sys.maxsize를 통해 int형의 최대값을 알 수 있다.

 


처음 생각했던 알고리즘의 문제점(틀린이유)

더보기

try1

(1) 처음 min[0]값을 설정할 때 arr내 가장 큰 값을 사용하면 될 거란 생각에 min[0] = arr[R]을 활용했다.

이러니 두 값의 합이 arr[R]보다 클 경우(arr의 모든 값이 양수인 경우) min[0]의 값이 업데이트 되지 않는 경우가 존재하였다.

-> min[0]을 초기화 할 때 sys.maxsize를 활용하도록 수정했다.

 

(2) 현재 값들의 합(sum)이 아닌 현재까지 나온 두 용액의 최소값을 L, R을 움직이는 기준으로 사용

→ sum이 항상 현재까지의 나온 두 용액의 최소값보다 작을 보장이 없기 때문에 sum을 비교에 활용해야함.

 

def input_func(N):
    arr = list((map(int,input().split())))
    arr.sort()
    return arr


def sum_func(arr):
    L = 0
    R = len(arr) - 1
    min = [arr[R], L, R] # 두 용액합의 현재까지의 최소값, L idx, R idx

    while L < R:
        sum = arr[L] + arr[R]
        if sum == 0:
            min[1], min[2] = arr[L], arr[R]
            break
        if abs(sum) < abs(min[0]):
            min[0] = sum
            min[1] = arr[L]
            min[2] = arr[R]
        if min[0] < 0: # 최소값이 0보다 작음, abs[0]으로 업데이트 되지 않을 수 있으므로 현재 값들의 합 이용 필요
            L += 1
        else: # 최소값이 0보다 크기 때문에
            R -= 1
    print(min[1], min[2])
    return


def main():
    N = int(input())
    arr = input_func(N)
    sum_func(arr)

if __name__=="__main__":
    main()

사용된 알고리즘

정렬, 이분탐색, 두 포인터

728x90