알고리즘
BOJ 2473: 세 용액
minbear
2023. 6. 27. 15:33
#BOJ 2473: 세 용액
2473번: 세 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 3 이상 5,000 이하의 정수이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상
www.acmicpc.net
#풀이
지난 번에 풀었던 용액과 거의 비슷한 문제이다. 세 용액을 골라서 합이 가장 0에 가까운 수를 오름차순으로 출력하는 문제이다.
용액 문제에서와 마찬가지로 lower_bound를 사용해서 해결할 수 있다.
if 문 안에서 3개를 다 더하면 int 형의 범위를 넘어가므로 long long 으로 캐스팅을 하든가 처음부터 long long 으로 받아야 한다.
abs(arr1[i] + arr1[j] + arr1[low + 1])
이 부분에서 오버플로우가 날 수 있다.
arr1의 형태가 int 형이라면 1,000,000,000 을 3번 더하면 int 범위를 넘어간다.
#코드
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int n;
vector<long long> arr1;
long long ans1 = 1e+9 + 1;
long long ans2 = 1e+9 + 1;
long long ans3 = 1e+9 + 1;// 지수표기법은 붙어야 에러가 안난다.
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 0; i < n; i++) {
int num;
cin >> num;
arr1.push_back(num);
}
sort(arr1.begin(), arr1.end());
for (int i = 0; i < n - 1; i++) {
for (int j = i + 1; j < n; j++) {
int low = lower_bound(arr1.begin(), arr1.end(), -1 * (arr1[i] + arr1[j]))
-arr1.begin();
if (low + 1 < n && i != low + 1 && j != low+1 && abs(arr1[i] + arr1[j] + arr1[low + 1]) < abs(ans1 + ans2 + ans3)) {
ans1 = arr1[i];
ans2 = arr1[j];
ans3 = arr1[low+1];
}
if (low < n && i != low && j != low && abs(arr1[i] + arr1[j] + arr1[low]) < abs(ans1 + ans2 + ans3)) {
ans1 = arr1[i];
ans2 = arr1[j];
ans3 = arr1[low];
}
if (low - 1 >= 0 && i != low -1 && j != low -1 && abs(arr1[i] + arr1[j] + arr1[low -1]) < abs(ans1 + ans2 + ans3)) {
ans1 = arr1[i];
ans2 = arr1[j];
ans3 = arr1[low - 1];
}
}
}
vector<long long > v;
v.push_back(ans1);
v.push_back(ans2);
v.push_back(ans3);
sort(v.begin(), v.end());
for (int i = 0; i < 3; i++)
cout << v[i] << ' ';
cout << '\n';
return 0;
}