티스토리 뷰
문제링크
( https://www.acmicpc.net/problem/2470 )
분류
- TwoPointers Algorithm
1. 풀이 힌트
- 주어진 용액들을 오름차순으로 정렬한 뒤, 양쪽 끝에 포인터를 두어 두 용액의 합이 0보다 크면 오른쪽 포인터를 왼쪽으로 한칸, 0보다 작으면 왼쪽 포인터를 오른쪽으로 한칸 옮기면서 두 포인터가 만날때 까지 각각의 합을 구하고, 도출된 합 중에서 0과 가장 가까운 결과에 해당하는 포인터가 지목하는 용액의 값을 오름차순으로 출력하면 된다.
2. 풀이 과정
1) 밑과 같이 각 용액이 주어졌을 때 먼저 오름차순으로 정렬한다
-2 | 4 | -99 | -1 | 98 |
2) 오름차순으로 정렬된 용액들
-99 | -2 | -1 | 4 | 98 |
3) 양쪽 끝에 포인터를 둔다
- 왼쪽 끝의 포인터는 파랑색으로 표현, 오른쪽 포인터는 빨간색으로 표현
-99 | -2 | -1 | 4 | 98 |
4) 각 포인터가 위치한 두 용액의 합을 구한다
- 포인터가 양 끝에 위치하므로 두 용액의 합을 구하면 -1이 나온다(-99 + 98)
5) 포인터에 위치한 두 용액 합의 결과가 마이너스이면 왼쪽(파란색) 포인터를 오른쪽으로 한칸 옮긴다.
- 두 용액의 합이 마이너스가 나왔다는 뜻은 두 용액의 값중 마이너스 용액의 값이 크다는 뜻이므로 좀 더 작은 마이너스를 가진 용액으로 포인터를 옮기기위해 왼쪽 포인터를 오른쪽으로 한칸 옮기는 것이다.
-99 | -2 | -1 | 4 | 98 |
6) 포인터를 옮겼으면, 두 포인터가 가르키는 두 용액의 합을 구한다
- 결과는 96으로 이번에는 두 용액 합이 플러스가 됐다. 플러스 일때는 오른쪽(빨간색) 포인터를 왼쪽으로 한 칸 옮긴다.
7) 과정 반복
- 두 포인터가 만날 때 까지 위와 같은 과정을 반복하고, 각 과정을 시행하면서 나온 두 용액의 합은 따로 하나의 배열에 저장한다.
8) 배열에 저장된 값중에 0과 가장 가까운 값을 나타내는 두 용액이 정답이된다.
2. 풀이 과정
3. 코드 풀이 (Java)
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class TwoSolutions {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n]; // 용액들을 저장할 배열
int[] dp = new int[n - 1]; // 두 용액의 합을 저장할 배열
StringTokenizer st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) { // 용액 저장
arr[i] = Integer.parseInt(st.nextToken());
}
Arrays.sort(arr); // 오름차순으로 정렬
int pL = 0; // 왼쪽 포인터
int pR = n - 1; // 오른쪽 포인터
int result = arr[pL] + arr[pR]; // 0과 가장 가까운 값을 비교하기 위한 변수 선언
int resultPL = arr[pL]; // 0과 가장 가까운 값을 이루고 있는 용액 1
int resultPR = arr[pR]; // 0과 가장 가까운 값을 이루는 용액 2
for (int i = 0; i < n - 1; i++) {
dp[i] = arr[pL] + arr[pR];
if (Math.abs(dp[i]) < Math.abs(result)) { // 결과값 최신화
result = dp[i];
resultPL = arr[pL];
resultPR = arr[pR];
}
// 두 용액 합의 결과에 따라 포인터 이동
if (dp[i] > 0) {
pR--;
} else if (dp[i] < 0) {
pL++;
} else { // 두 용액의 합이 0이면 for문을 종료
break;
}
}
// 결과 출력
System.out.println(resultPL + " " + resultPR);
}
}
'Algorithm > 백준' 카테고리의 다른 글
백준 2667 단지번호붙이기 (typescript, javascript) (0) | 2021.09.21 |
---|---|
Backjoon(백준) 1699- 제곱수의 합 (Java) (0) | 2020.05.09 |
Backjoon(백준) 9251- LCS (Java) (0) | 2020.05.05 |
Backjoon(백준) 11054 - 가장 긴 바이토닉 부분 수열(Java) (0) | 2020.05.02 |
Backjoon(백준) 11053번 - 가장 긴 증가하는 부분 수열(Java) (0) | 2020.05.02 |
- 20200403
- 20200317
- 20200319
- 20200406
- 백준
- chapter7
- 20200427
- 20200804
- 20200622
- 20200421
- 20200424
- 20200504
- 20200428
- 20201204
- likelion
- 20200417
- 20200330
- 20200510
- 20200413
- 20200503
- 생활코딩리눅스
- 20200624
- 20200425
- 20200420
- chapter8
- 20200415
- 20200512
- 20200429
- 20200502
- 20200423
- Total
- Today
- Yesterday