https://www.acmicpc.net/problem/2467
2467번: 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하의 정수이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 오름차순으로 입력되며, 이 수들은 모두 -
www.acmicpc.net
입력받은 배열에서 합이 최소가 되는 두 성분을 출력하는 문제이다. 이미 정렬이 되어 있으므로 이분 탐색을 활용해도 되지만 배열의 모든 성분에 대해 이분 탐색을 진행해야 하므로 시간 복잡도가 배열의 길이 n에 대해 O(nlogn)이 된다. 반면 투 포인터를 이용하면 배열을 선형 탐색을 이용해 접근하므로 시간 복잡도는 배열의 길이 n에 대해 O(n)이 된다.
#include <iostream>
using namespace std;
#define MAX_N 100000
int liq[MAX_N + 1];
// 정수를 입력받아 그 절댓값을 반환
int abs(int n) { return n >= 0 ? n : -n; }
int main() {
// 입출력 속도 향상
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// l, r: 배열을 탐색하기 위한 두 인덱스
// a, b: 정답을 출력하기 위한 두 인덱스
int l = 1, r, a = 0, b = 1;
// 용액의 수와 각 용액의 특성값을 입력
cin >> r;
for (int i = l; i <= r; i++) cin >> liq[i];
// 투 포인터 실행
while (l < r) {
// 두 용액을 합쳤을 때 특성값이 기존 특성값보다 작다면 그 포인터쌍을 저장
if (abs(liq[l] + liq[r]) < abs(liq[a] + liq[b])) { a = l; b = r; }
// 포인터를 합친 용액의 특성값에 따라 이동
liq[l] + liq[r] > 0 ? r-- : l++;
}
// 합친 용액의 특성값이 0에 가장 가까운 두 용액의 특성값을 출력
cout << liq[a] << ' ' << liq[b] << '\n';
return 0;
}
'알고리즘 > 문제 풀이' 카테고리의 다른 글
2473번: 세 용액 (0) | 2021.12.17 |
---|---|
2468번: 안전 영역 (0) | 2021.12.16 |
2448번: 별 찍기 - 11 (0) | 2021.12.16 |
2447번: 별 찍기 - 10 (0) | 2021.12.16 |
2446번: 별 찍기 - 9 (0) | 2021.12.16 |