일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 백준 1647번 도시 분할 계획 - java
- 프로그래머스 java
- StringTokenizer
- 백준 1043번 거짓말 - java 분리 집합
- 프로그래머스
- 백준 3190번
- Stack
- dp
- 백준 14938번 서강그라운드
- StringBuilder
- 백준 2473번 세 용액 - java
- 백준 2467번 용액 자바 - 이분탐색
- hash
- 프로그래머스 자바
- map
- toUpperCase
- 백준 1197번 최소 스패닝 트리 - java
- 최소 힙 1927
- Java
- HashSet
- mysql hy000 에러
- kotlin
- 백준 1806번 부분합 java
- replace()
- HashMap
- append
- 코틀린기초
- 백준 1541
- 18111번 마인크래프트 - java 구현
- ac 5430번
Archives
- Today
- Total
말하는 컴공감자의 텃밭
백준 2473번 세 용액 - Java 이분탐색 본문
728x90
오늘은 해장 알고리즘..
비전공자와 함께 토크토크하며 시작합니다..
문제를 정리하면 배열이 주어지고, 해당 배열에서 3가지를 선택해서 0에 가장 가깝게 만드는게 관건이다.
입력은 3 <= N <= 5000 이고, 숫자는 -10억 ~ 10억 까지로 주어진다.
🔹 인풋은 5,000 숫자 세개를 모두 탐색하게되면 N³. = 125,000,000,000 이 된다.
시간 제한 1초, 10⁸ 안팎이어야 하므로 이분탐색을 활용해서 시간을 log 대로 줄여보자.
해결 프로세스
1. 숫자를 정렬하자.
2. 두개를 먼저 이중 포문으로 고정하자.
3. 나머지 숫자는 고정된 값 + 탐색하는 값으로 0과 가까운지 확인하며 이분탐색으로 찾자.
4. 저장된 용액보다 0과 가깝다면 업데이트 해자.
5. 0을 만들거나, 모든 경우의 수를 따졌다면 최적의 결과를 출력하자.
정렬에 N log N, 이중 포문 N², 이진 탐색 log N = O(N² * log N) 으로 줄일 수 있다.
N ² × log N ≈ 25,000,000 × 12.3 ≈ 307,500,000 이므로 1초 안팎으로 가능하다.
작성해보자
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 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)); StringBuilder sb = new StringBuilder(); StringTokenizer st = new StringTokenizer(br.readLine()); int N = Integer.parseInt(st.nextToken()); long[] arr = new long[N]; st = new StringTokenizer(br.readLine()); for (int i = 0; i < N; i++) { arr[i] = Integer.parseInt(st.nextToken()); } Arrays.sort(arr); long best = Long.MAX_VALUE; long[] result = new long[3]; // 숫자 두개 고정. for (int i = 0; i < N - 2; i++) { for (int j = i + 1; j < N - 1; j++) { long now= arr[i]; long next = arr[j]; int min = j + 1; int max = N - 1; int mid = 0; long sum = 0; while (min <= max) { mid = (min + max) / 2; sum = now + next + arr[mid]; // 이전 기록보다 좋은 용액이라면 업데이트 if (Math.abs(sum) < Math.abs(best)) { best = sum; result[0] = now; result[1] = next; result[2] = arr[mid]; } if (sum > 0) { max = mid - 1; } else if (sum < 0) { min = mid + 1; } else { // 0 을 만든 System.out.println(now + " " + next + " " + arr[mid]); return; } } } } System.out.println(result[0] + " " + result[1] + " " + result[2]); } } | cs |
728x90
'알고리즘 > Backjoon - Java' 카테고리의 다른 글
백준 14938번 서강그라운드 - Java 다익스트라 (0) | 2024.10.14 |
---|---|
백준 1043번 거짓말 - Java 분리 집합 (0) | 2024.08.30 |
백준 1197번 최소 스패닝 트리 - Java (0) | 2024.08.28 |
백준 18111번 마인크래프트 - Java 구현 (0) | 2024.08.27 |
백준 1647번 도시 분할 계획 - Java 최소 스패닝 트리 (0) | 2024.08.26 |
Comments