문제 출처
1. 문제설명
N
개의 수열이 주어진다.
- 수열에서 3개의 수를 뽑아 0에 가장 가까운 세 개의 수를 구하라
2. 알고리즘 설계
- 이전 문제와 달리, 0인 경우가 있다고 단정할 수 없다.
- 투 포인터 방식으로 접근해야 한다.
- 로직
- for loop를
i-2
번째까지 실행한다.
left=i+1, right=n-1
로 설정
- 매순간
arr[i] + arr[left] + arr[right]
가 좀 더 0에 가까운 수인지 체크
- 값이 0보다 작다면
left++
, 그 외의 경우 right--
3. 전체 코드
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll INF = 1000000005;
ll n, arr[5005];
vector<ll> ans;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
ans = {INF, INF, INF};
cin >> n;
for(int i=0; i<n; i++)
cin >> arr[i];
sort(arr, arr+n);
for(int i=0; i<n-2; i++) {
int left=i+1, right=n-1;
while(left < right) {
ll cmp = arr[i] + arr[left] + arr[right];
if(abs(ans[0]+ans[1]+ans[2]) > abs(cmp))
ans = {arr[i], arr[left], arr[right]};
(cmp < 0) ? left++ : right--;
}
}
for(ll a : ans) cout << a << ' ';
return 0;
}
4. 소감
- arr의 값 세 개를 더할 때, 최대/최소 값이 +-10억이므로, int overflow가 발생할 수 있다.
- 그냥 전부
long long
으로 선언해버리자