알고리즘/BOJ

[백준] 2473_세 용액 (투 포인터 이용)

엉아_ 2021. 10. 8. 00:36
728x90

📕 문제

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

 

2473번: 세 용액

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

www.acmicpc.net

 

💡 풀이법

1. 이 문제는 포인터가 총 세개이기 때문에 한 포인터는 고정시키고 두 포인터를 욺직여야 한다.

2. 투포인터를 이용하려면 먼저 리스트가 오름차순 정렬이 되어있어야 한다.

3. 가장 앞의 포인터를 for문을 돌면서 먼저 i로 지정해주고, left 포인터는 i+1, right 포인터는 N-1로 해준다.

4. 세 값들의 합이 0보다 크면 right를 -1 해주고, 0보다 작으면 left를 +1 해준다.

5. total(세 숫자의 합의 절대값)이 answer_sum(0과 가장 가까운 합을 담는 변수)보다 작다면 answer(세개의 값이 담길 리스트)를 변화시켜주고, answer_sum을 total로 변화시켜준다.

6. 만약 total이 0이라면 flag를 True로 바꿔주고 return 한다.

( flag는 함수 밖의 for문도 바로 빠져나가기 위해 만들어준 break)

 

def two_pointer(lst, start, end):
    global mark, answer_sum, flag
    left, right = start, end

    while left < right:
        total = mark + lst[left] + lst[right]

        if abs(total) < answer_sum:
            answer[0] = mark
            answer[1] = lst[left]
            answer[2] = lst[right]
            answer_sum = abs(total)
                
            if total == 0:
                flag = True
                return
        
        if total > 0:
            right -= 1
        elif total < 0:
            left += 1
    
    
N = int(input())
nums = list(map(int,input().split()))
nums.sort()
answer_sum = float('inf')
answer = [0]*3
flag = False
for i in range(N-2):
    mark = nums[i]
    two_pointer(nums, i+1, N-1)
    if flag:
        break
print(*answer)