변수 설정
N : 전체 용액의 수
A : 주어진 용액의 특성값
함수의 매개변수 : start, end
이 문제에서는 target 설정이 불필요하다. A 리스트의 값을 더한 것의 절댓값 끼리의 비교이며, 0과의 거리가 가장 짧은 것을 구한다면, 절댓값이 가장 작은 수를 반환하면 되기 때문이다.
문제 특성 상, 여러가지의 정답을 허용하기 때문에 어떤 값이라도 출력을 하고 그 값의 합이 0과 가장 가까운 값이라면 Pass를 준다.
최종 코드
def salt (start, end):
best = float('inf')
answer = (0, 0)
while start < end:
sum = A[start] + A[end]
if abs(sum) < abs(best):
best = sum
answer = (A[start], A[end])
if sum < 0 :
start += 1
else :
end -= 1
return answer
N = int(input())
A = sorted(list(map(int, input().split())))
start = 0
end = len(A)-1
result = salt(start, end)
if len(A) == 2:
print(f"{A[0]} {A[1]}")
else : print(*result)
코드를 구성하며 어려운 점은, sum 값을 리스트에서 직접 받아와야 한다는 점과, 타겟 설정이 불필요하다라는 생각에 도달하기 까지 시간이 오래걸렸다. 그리고 코드를 작성 후, 예외 상황에 대한 추가적인 고려가 필요했던 부분이 이 문제를 더 어렵게 만드는것이라 생각된다. 디버깅 툴을 이용하면 바로바로 어떤 부분에서 내가 예외 처리를 놓쳤는지 알 수 있어서 오래 걸리지는 않았다.
한가지 base 조건으로 기억해야 할 점은 best 값의 설정이다.
best = float(’inf’) : best 값을 무한대로 설정하여 어떤 값의 합도 이 값보다 작을 수 있도록 초기화 한다.
시행착오 1. 주어진 용액의 수가 2개인 경우 예외 처리를 해야한다
이 경우는 문제에서 주어지는 입력값에서 놓치는 부분이었다. 문제는 N은 2 이상 100,000 이하라고 주어진다.
즉 용액은 항상 두 개 이상 주어지며 N = 2인 케이스도 고려해야 한다. 이 경우 두 수의 조합이 한 가지뿐이므로 투 포인터를 돌릴 필요 없이, 입력 그대로 오름차순 출력해주면 된다. 마지막 출력 부분에 아래 코드를 추가하여 해결하였다.
if len(A) == 2:
print(f"{A[0]} {A[1]}")
else : print(*result)
시행착오 2. start < end 이어야 한다 (start ≤ end ❌)
용액 간의 특성 값의 비교를 해야 하기 때문에, 한 용액이 두번 출력되면 안된다. start ≤ end 인 경우, 나와 나 자신을 비교하게 되고, 그 값이 만약 0, 0 이라면 그 값이 항상 정답이 된다. 이 경우에는 start와 end가 만날 수 없도록 지정을 해줘야 한다. 이 부분이 이전에 풀었던 이진탐색 문제와 다른 점이었지만, 백준의 디버깅 툴을 이용하면 쉽게 알아낼 수 있었다.
'IT 성장기 (교육이수) > 알고리즘 문제풀이' 카테고리의 다른 글
백준 : 1197 최소 스패닝 트리 (0) | 2025.03.29 |
---|---|
백준 : 11053 가장 긴 증가하는 부분수열 (0) | 2025.03.23 |
백준 : 2110 공유기 설치 (0) | 2025.03.22 |
백준 : 2805 나무 자르기 (0) | 2025.03.21 |
백준 : 9095 - 1, 2, 3 더하기 (0) | 2025.03.20 |