Coding Test/백준
[백준] 2470 두 용액 - 자바
lsh2613
2023. 9. 12. 15:48
https://www.acmicpc.net/problem/2470
2470번: 두 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00
www.acmicpc.net
문제 풀이
투 포인터 문제로 이진탐색을 생각하면 쉽게 해결할 수 있다.
두 용액을 섞었을 때 혼합값이 0에 가까워야 한다. 값을 비교하여 0보다 큰 수(양수)는 작아지도록, 0보다 작은 수(음수)는 커지도록 설정해주기 위해서 원하는 값을 참조할 수 있어야 한다. 따라서 이 로직을 적용시키기 위해 정렬을 먼저 해줘야 한다. (이진 탐색에서도 정렬을 먼저 하듯이)
숫자만 봐도 감이 올 것이다. 양쪽에 포인터 left, righr를 두고 이 두 값의 합이 0에 가까워지도록 포인터를 처리해주면 된다.
- 값을 작게해주기 위해선 right를 왼쪽으로 움직이고
- 값을 키우기 위해선 left를 오른쪽으로 옮긴다
단, 계속해서 위 로직이 적용되지는 않을 것이다. 포인터를 옮겼을 때 이전에 구한 값보다 0에서 멀리 떨어져 있다면, 즉 이전혼합값보다 포인터를 변경 후 혼합값의 절댓값이 더 크다면 위 로직을 종료하면된다.
코드
package 백준;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
public class b2470 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] nums = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt)
.toArray();
Arrays.sort(nums);
int left = 0, right = N - 1;
int minSum = Integer.MAX_VALUE;
int[] result = new int[2];
while (left < right) {
int sum = nums[left] + nums[right];
if (Math.abs(sum) < minSum) {
minSum = Math.abs(sum);
result[0] = nums[left];
result[1] = nums[right];
}
if (sum < 0) {
left++;
} else {
right--;
}
}
System.out.println(result[0] + " " + result[1]);
}
}