https://www.acmicpc.net/problem/2470
2470번: 두 용액
첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00
www.acmicpc.net
풀이
2 <= N <= 100,000 이므로 O(n)의 시간복잡도로 문제를 풀어야 한다.
두 용액 값을 더한 값 중 0에 가까운 값을 구해야 하므로, 용액 값을 정렬한 다음 투포인터 알고리즘을 사용하여 O(n)의 시간복잡도로 문제를 풀었다.
로직
1. 특성용액을 정렬한다.
2. 투포인터 알고리즘을 사용한다. 초기값: l = 0, r = n-1
- 두 용액의 특성값의 절대값을 구해서 min값과 ans1, ans2 값을 업데이트한다.
- 두 용액의 특성값이 0보다 작으면 l++, 0보다 크면 r--를 한다. 0이면 반복문을 탈출한다.
코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
//StringBuilder sb = new StringBuilder();
int n = Integer.parseInt(br.readLine());
ArrayList<Integer> list = new ArrayList<>();
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
list.add(Integer.parseInt(st.nextToken()));
}
Collections.sort(list);
int l = 0, r = n - 1; // 투 포인터
int ans1 = 0, ans2 = 0; // 두 용액
boolean flag = false; // 특성값이 0이 되는 경우 true
int min = Integer.MAX_VALUE; // 두 용액의 특성값의 최솟값
while (l < r) {
int sum = 0;
sum += list.get(l);
sum += list.get(r);
if (min > Math.abs(sum)) {
min = Math.abs(sum);
ans1 = list.get(l);
ans2 = list.get(r);
}
if (sum < 0) {
l++;
}
else if (sum > 0) {
r--;
}
else {
flag = true;
bw.write(list.get(l) + " " + list.get(r));
break;
}
}
if (!flag) {
bw.write(ans1 + " " + ans2);
}
bw.flush();
br.close();
bw.close();
}
}
728x90
'Algorithm 문제 풀이 > 백준' 카테고리의 다른 글
[백준] 17144번 : 미세먼지 안녕! - 자바[Java] (0) | 2023.08.16 |
---|---|
[백준] 16719번 : ZOAC - 자바[Java] (0) | 2023.08.15 |
[백준] 2579번 : 계단 오르기 - 자바[Java] (0) | 2023.08.03 |
[백준] 2003번 : 수들의 합 - 자바[Java] (0) | 2023.07.25 |
[백준] 17135번 : 캐슬 디펜스 - 자바[Java] (0) | 2023.07.05 |