728x90
📌 링크: https://www.acmicpc.net/problem/2470
📌 총평: 이문제 이진탐색으로 분류되어있는데 낚시다. 투포인터 문제다.
📌 헷갈렸던 부분:
✅ 이 문제는 양쪽 끝을 계속해서 비교하는 문제여서, 핵심은 양끝의 합 >0 이면 오른쪽-=1, 양끝의 합 <0이면 왼쪽+=1을 하는거였다.
나는 양끝의 합의 부호를 기준으로 보지 않고 바로 직접값이랑 합의 값을 비교해서 틀렸다. abs(arr[s] + arr[e-1]) < abs(arr[s] + arr[e]) 왜 절댓값 비교를 하면 안되냐하면, 값이 수렴하지 않고 진동할 수 있기 때문이다. 현재 수렴해야하는 값은 양끝의 합=0이 되는 것,
즉, 0으로 값이 수렴해야하므로 0이 기준이 되어야한다. 그래서 0보다 합이 크면 합을 줄이는 쪽인 왼쪽-=1 ~ 이런식으로 왼쪽,오른쪽 값을 조절하는 거다.
✅ 절댓값을 빠뜨려서 자꾸 틀렸다.
📌 풀이 1 (left, right 조정)
N = int(input())
arr = list(map(int,input().split()))
arr.sort()
left,right=0,N-1
min_sum=abs(arr[left]+arr[right])
final=[arr[left],arr[right]]
while left<right:
current_sum = arr[left]+arr[right]
if min_sum > abs(current_sum):
min_sum=abs(current_sum)
final=[arr[left],arr[right]]
if current_sum == 0:
break
elif current_sum>0:
right-=1
else:
left+=1
print(*final)
📌 풀이 2 (left for문 돌리면서 right 조정)
N = int(input())
arr = list(map(int,input().split()))
arr.sort()
e = N-1
min_sum = int(1e9)*2
left,right=0,0
for s in range(N):
while s<e:
current_sum = arr[s]+arr[e]
if abs(current_sum)<min_sum:
left,right=s,e
min_sum=abs(current_sum)
if current_sum>0:
e-=1
else:
break
print(arr[left],arr[right])
728x90
'코딩테스트 > 투포인터' 카테고리의 다른 글
[투포인터] (프로그래머스_178870) 연속된 부분 수열의 합 (0) | 2024.10.01 |
---|---|
[투포인터] (이론+문제) 특정한 합을 가지는 부분 연속 수열 찾기 (0) | 2024.09.26 |