PS/C++
[백준 2470] 두 용액( + 2467번)
siyamaki
2024. 7. 10. 13:30
https://www.acmicpc.net/problem/2470
배열의 주어진 값들 중 두 값을 선택해서 더한 결과 중 0에 가까운 두 수를 찾는 문제다
투 포인터, 이분탐색으로도 해결 가능하지면 정렬을 이용해서 해결했다.
compare 함수를 구현하면 정렬기준을 직접 정의할 수 있는데 더한 결과 중 0에 가깝다는건 연속된 두 값의 차이가 가장 작아야 하므로 compare함수를 아래처럼 구현해주면 절대값을 한 수들이 0과 가까운 수 기준으로 정렬된다
bool compare(int a, int b) {
return abs(a) - abs(b) > 0;
}
아래 케이스는 코드를 짜면서 만든 케이스인데
정렬 전
10
-10 -8 -2 0 1 2 5 13 14 17
정렬 후
0 1 -2 2 5 -8 -10 13 14 17
위 compare로 정렬하고 나서 v[i]와 v[i + 1]을 비교해서 diff값을 갱신하면 된다.
시간복잡도는 정렬에 O(logN), 비교에 O(N)이므로 O(logN + N)정도가 된다.
덤으로 2467번 용액 문제도 코드를 그대로 내면 맞는다(https://www.acmicpc.net/problem/2467)
#include <bits/stdc++.h>
#define FASTIO ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
using namespace std;
bool compare(int a, int b) {
return abs(a) - abs(b) < 0;
}
int main() {
FASTIO
int n;
cin >> n;
vector<int> v;
for(int i = 0; i < n; i++) {
int k; cin >> k;
v.push_back(k);
}
sort(v.begin(), v.end(), compare);
int mn = 0, mx = 0, diff = 2000000001;
for(int i = 0; i < n - 1; i++) {
if(diff > abs(v[i] + v[i + 1])) {
diff = abs(v[i] + v[i + 1]);
mn = v[i];
mx = v[i + 1];
if(diff == 0) {
break;
}
}
}
if(mn > mx) {
swap(mn, mx);
}
cout << mn << ' ' << mx;
}