J 크 2023. 11. 7. 23:59
728x90
반응형

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

 

2470번: 두 용액

첫째 줄에는 전체 용액의 수 N이 입력된다. N은 2 이상 100,000 이하이다. 둘째 줄에는 용액의 특성값을 나타내는 N개의 정수가 빈칸을 사이에 두고 주어진다. 이 수들은 모두 -1,000,000,000 이상 1,000,00

www.acmicpc.net

두 싸피


※  문제를 요약하면 아래와 같습니다.

▶ 산성 용액과 알칼리성 용액은 각각 1~10억, -1~10억 까지의 특성값 존재

▶ 여러 가지 용액들 중 두 용액을 골라 혼합하여 특성값을 0에 가장 가까운 용액을 만드는 것이 목표

▶ 가장 0에 가깝게 합성할 수 있는 두 용액을 찾는 프로그램 작성

▶ Input : 첫번째 줄에 용액의 수 N, 이후 N개의 정수에 용액값이 공백을 구분으로 입력

▶ Output : 특성값이 0에 가장 가까운 용액을 만들어내는 두 용액의 특성값 출력

                        특성값이 0에 가장 가까운 용액을 만들어내는 경우가 두 개 이상일 경우에는 그 중 아무것이나 하나를 출력한다.


◈ Input - 1

5
-2 4 -99 -1 98

◈ Output - 1

-99 98

 ◎  코드 작성 전, 아래와 같이 솔루션을 정리하였습니다.

▶ N개의 용액 값을 1차원 배열에 입력 받은 후 정렬

투 포인터 탐색 활용, 배열의 가장 왼쪽값 (배열 내 최소값) 과 배열의 가장 오른쪽값 (배열 내 최댓값) 부터 탐색

▶ 왼쪽값과 오른쪽값을 더하여 절댓값을 씌운후, Min과 비교하여 최소값 저장

최소값 저장 시 해당 최소값을 만든 두 용액의 값을 저장 ( 코드 내 nAcid, nAlkalic )

▶ 왼쪽값을 오른쪽으로 한 칸 밀었을 때의 sum과 오른쪽값을 왼쪽으로 한 칸 밀었을 때의 sum을 비교

     값이 더 낮은 곳으로 포인터 방향을 이동


import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

    public static void main(String[] args) throws IOException {

        BufferedReader bReader = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bWriter = new BufferedWriter(new OutputStreamWriter(System.out));

        // N개의 갯수만큼 값을 입력받자
        int N = Integer.parseInt(bReader.readLine());
        int[] narrSolution = new int[N];
        StringTokenizer st = new StringTokenizer(bReader.readLine());
        for(int i = 0 ; i < N; i++) {
            narrSolution[i] = Integer.parseInt(st.nextToken());
        }

        // 정렬 함 해주고
        Arrays.sort(narrSolution);

        int nMin = Integer.MAX_VALUE;
        int nSum = 0;
        int nLeft = 0;
        int nRight = N-1;
        // 결과 값을 저장하자
        int nAcid = 0;
        int nAlkalic = 0;
        while(nLeft < nRight ) {
            // 두개의 합을 더한 값과 최소값을 비교하여
            // 최소값일 경우, 두 값을 저장한다.
            nSum = narrSolution[nLeft] + narrSolution[nRight];
            if(nMin > Math.abs(nSum)) {
                nMin = Math.abs(nSum);
                nAcid = narrSolution[nLeft];
                nAlkalic = narrSolution[nRight];
            }

            if(nSum == 0)
                break;

            // 오른쪽이랑 왼쪽으로 옮겼을 때 중
            // 최소값인 곳으로 옮겨주자
            if(Math.abs(narrSolution[nLeft+1] + narrSolution[nRight]) > Math.abs(narrSolution[nLeft] + narrSolution[nRight-1]))
                nRight--;
            else
                nLeft++;
        }

        bWriter.write(nAcid + " " + nAlkalic);
        bWriter.close();
    }

}

Good Luck! (피드백 감사합니다!)