[백준/Java] 2470: 두 용액

2025. 9. 29. 22:26·코딩테스트/백준

https://www.acmicpc.net/problem/2470

 


 

문제

연구소에 많은 종류의 산성 용액과 알칼리성 용액이 있음

각 용액에는 그 용액의 특성을 나타내는 정수가 주어짐

  • 산성: 1부터 1,000,000,000의 양의 정수
  • 알칼리성: -1부터 -1,000,000,000까지의 음의 정수

이제 두 용액을 혼합해서 특성값이 0에 가장 가까운 용액을 만들 거임

주어진 용액들의 특성값이 [-2, 4, -99, -1, 98] 인 경우 특성값이 -99인 용액 + 98인 용액 = 특성값이 -1인 용액을 만들 수 있음

이 용액이 특성값이 0에 가장 가까운 용액

 

주어진 용액의 특성값 중 두 개의 서로 다른 용액을 혼합했을 때, 그 값이 0에 가장 가까운 용액을 만들어내는 두 용액을 찾아야 함

 

제한사항

  • 2 <= 전체 용액의 수 N <= 100,000
  • - 1,000,000,000  <= 각 용액의 각 특성값 <= 1,000,000,000
  • N개의 용액들의 특성값은 모두 다름
  • 산성 용액만 주어지거나 알칼리성 용액만 주어지는 경우도 있음

 


 

풀이

투 포인터 활용 문제

 

1. 입력 받은 정수들을 하나의 배열에 저장하여 오름차순 정렬

  • 배열의 맨 앞에 있는 수는 강한 알칼리성, 맨 뒤에 있는 수는 강한 산성을 나타냄

 

2. 두 포인터 설정

  • 왼쪽 포인터 start는 맨 처음 (가장 작은 값, 가장 강한 알칼리성)
  • 오른쪽 포인터 end는 맨 끝 (가장 큰 값, 가장 강한 산성)

 

3. 합 계산 & 포인터 이동

  • 현재 위치하고 있는 두 용액의 합 계산
    • 매 계산마다 절댓값이 가장 작은 합과 그 두 용액을 기록
  • 합이 0보다 큰 경우 => 합을 작게 만들어야 0에 가까워짐, end--;
  • 합이 0보다 작은 경우 => 합을 크게 만들어야 0에 가까워짐, start++;
  • 합이 0인 경우 => 이 때의 두 용액이 답, 탐색 중지

 

주의

  • start < end 인 상황에만 반복 (서로 다른 용액만 조합해야 하므로)

 

코드

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();

        int N = Integer.parseInt(br.readLine());
        int[] solution = new int[N];

        StringTokenizer st = new StringTokenizer(br.readLine());
        for (int i = 0; i < N; i++) {
            solution[i] = Integer.parseInt(st.nextToken());
        }

        Arrays.sort(solution);  // 정렬 (알칼리성 <--> 산성)

        int start = 0;
        int end = solution.length - 1;

        // 두 용액의 합을 구할 때마다 지금까지 구한 합의 최소값을 구하고 그 두 용액도 같이 기록
        int minSum = 2_000_000_000;
        int sol1 = start, sol2 = end;

        while (start < end) {
            int sum = solution[start] + solution[end];
            
            // 최소값 갱신
            if (Math.abs(sum) < Math.abs(minSum)) {
                minSum = sum;
                sol1 = start;
                sol2 = end;
            }

            if (sum > 0) {
                // 두 용액의 합이 0보다 큰 경우 산성이 강하다는 것
                // 따라서 오른쪽에 있는 포인터를 앞으로 이동
                end--;
            } else if (sum < 0) {
                // 두 용액의 합이 0보다 작은 경우 알칼리성이 강하다는 것
                // 따라서 왼쪽에 있는 포인터를 앞으로 이동
                start++;
            } else {
                // 두 용액의 합이 0과 같은 경우
                break;
            }
        }

        sb.append(solution[sol1]).append(' ').append(solution[sol2]);
        System.out.println(sb);
    }

}
저작자표시 (새창열림)

'코딩테스트 > 백준' 카테고리의 다른 글

[백준/Java] 10986: 나머지 합  (0) 2025.10.13
[백준/Java] 2579: 계단 오르기  (0) 2025.10.02
[백준/Java] 1932: 정수 삼각형  (2) 2025.08.01
[백준/Java] 1325: 효율적인 해킹  (1) 2025.06.04
[백준/Java] 12542: Building a House (Large)  (0) 2025.05.28
'코딩테스트/백준' 카테고리의 다른 글
  • [백준/Java] 10986: 나머지 합
  • [백준/Java] 2579: 계단 오르기
  • [백준/Java] 1932: 정수 삼각형
  • [백준/Java] 1325: 효율적인 해킹
naahy
naahy
  • naahy
    종합장
    naahy
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Java
      • SpringBoot
      • Git
      • 트러블슈팅
      • Vue.js
      • Kotlin
      • Node.js
      • 코딩테스트
        • 백준
        • 프로그래머스
      • 스터디
        • CS
        • 알고리즘
      • -
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 인기 글

  • 태그

    SpringBoot
    프로그래머스
    github
    React
    Nexacro
    Java
    백준
    bfs
    브루트포스
    백트래킹
    node.js
    mongodb
    코틀린
    트러블슈팅
    Kotlin
    cs
    API
    투포인터
    자바
    이분탐색
  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
naahy
[백준/Java] 2470: 두 용액
상단으로

티스토리툴바