

문제 출처 : https://www.acmicpc.net/problem/2470
난이도 : 골드 5
이 문제의 본질은 배열에서 서로 다른 두 숫자를 골라 합이 0에 가장 가까워지도록 만드는 것이다.
그리고 그 합이 가장 0에 가까워졌을 때의 두 숫자 자체를 출력해야 한다.
이를 효율적으로 해결하기 위해 배열을 먼저 정렬한 뒤,
양 끝에서 시작하는 투 포인터 방식을 사용한다.
우리는 “0에 가장 가까운 값”을 찾아야 하므로
각 시점의 합에 대해 절댓값 abs()를 기준으로 비교해야 한다.
또한 언제든 더 좋은 조합이 나올 수 있기 때문에,
현재까지의 최소 절댓값을 저장할 best를 충분히 큰 값(float('inf'))으로 초기화하고
매번 더 작은 절댓값이 나오면 이를 갱신하는 방식으로 접근한다.
이때마다 해당 조합의 두 값을 answer에 함께 저장해 두고,
모든 탐색이 끝난 뒤 abs(mix)가 가장 작았던 순간의 answer를 출력하면 된다.
import sys
input = sys.stdin.readline
# 산성(양수), 알칼리(음수)라는 설정이 있지만
# 결국은 "두 수의 합이 0에 가장 가까운 쌍"을 찾는 문제
N = int(input()) # 최대 100,000
nums = list(map(int, input().split()))
# 투 포인터를 쓰려면 정렬이 필수
nums.sort()
# 정렬된 배열에서 양 끝에서 시작
left = 0
right = N - 1
# abs(mix)의 최소값을 저장 (초기값은 아주 크게)
best = float('inf')
# 정답으로 뽑힌 두 용액 값 저장
answer = (0, 0)
while left < right:
mix = nums[left] + nums[right]
# 현재 조합이 더 0에 가까우면 갱신
if abs(mix) < best:
best = abs(mix)
answer = (nums[left], nums[right])
# 합이 양수면 너무 큰 상태 -> right를 줄여서 합을 낮춘다
if mix > 0:
right -= 1
# 합이 음수면 너무 작은 상태 -> left를 늘려서 합을 키운다
elif mix < 0:
left += 1
# mix == 0이면 이론상 최적이라 바로 종료
else:
break
print(answer[0], answer[1])
나는 계속 best를 갱신하는 방법이 아닌,
혼합물을 0과 비교하려고 했기에 해멨다.
import sys
input = sys.stdin.readline
INF = float('inf')
N = int(input())
nums = list(map(int,input().split()))
nums.sort()
left = 0
right = N-1
best_value = INF
best_pair = [None,None]
while left < right:
total = nums[left] + nums[right]
if abs(total) < best_value:
best_value = abs(total)
best_pair[0] = nums[left]
best_pair[1] = nums[right]
if total > 0:
right -= 1
elif total < 0:
left += 1
else:
print(nums[left], nums[right])
sys.exit(0)
print(best_pair[0],best_pair[1])