본문 바로가기
  • 개발공부 및 일상적인 내용을 작성하는 블로그 입니다.
코딩 테스트/그리디

백준 1541 - 잃어버린 괄호 (자바 - 그리디)

by 방구석 대학생 2023. 5. 31.

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

 

1541번: 잃어버린 괄호

첫째 줄에 식이 주어진다. 식은 ‘0’~‘9’, ‘+’, 그리고 ‘-’만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다

www.acmicpc.net

 

* 문제 요약

양수와 +, -, 그리고 괄호를 가지고 식을 만들었다. 그리고 나서 괄호를 모두 지웠다.

다시 괄호를 적절히 쳐서 이 식의 값을 최소로 만드는 프로그램을 작성하시오.

 

* 입력

첫째 줄에 식이 주어진다. 식은 0~9, +, - 만으로 이루어져 있고, 가장 처음과 마지막 문자는 숫자이다. 그리고 연속해서 두 개 이상의 연산자가 나타나지 않고, 5자리보다 많이 연속되는 숫자는 없다. 수는 0 으로 시작할 수 있다. 입력으로 주어지는 식의 길이는 50보다 작거나 같다.

 

* 출력

첫째 줄에 정답을 출력한다.

 

* 예시

 

* 해결 과정

최대한 큰 숫자를 뺄셈에 이용하는 상황을 만들면 식의 최소값에 가까운 값을 구할 수 있다.

그러므로 더하기 연산을 먼저 하여 최대한 큰 숫자를 만든 다음 남아있는 뺄셈 연산을 수행했다.

1. 먼저 - 기호를 기준으로 문자열을 나눠 배열에 저장했다. 이렇게 하면 + 기호로 이어져 있는 문자열은 하나의 인덱스 안에 함께 저장된다.

2. 배열을 탐색하며 + 기호를 가진 문자열이 발견될 경우 해당 문자열의 숫자를 모두 더해주고 그 값을 뺄셈에 활용할 int 배열에 다시 저장해준다.

3. 현재 탐색에서 + 기호가 발견되지 않은 경우 해당 숫자에는 아무런 조치도 취해주지 않고 그대로 뺄셈에 활용할 int 배열에 저장해준다.

4. 최종적으로 뺄셈에 활용할 연산에 들어있는 숫자들 하나하나에 뺄셈을 수행해주면서 나온 결과값을 출력해준다.

 

* 코드

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

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

        // 더하기를 먼저 해서 최대한 큰 숫자를 만든다음 뺄셈 연산을 수행한다.
        String[] inputArray = br.readLine().split("\\-");
        int[] numberArray = new int[inputArray.length];

        for(int i = 0; i < inputArray.length; i++){
            if(inputArray[i].contains("+")){
                String[] tempArray = inputArray[i].split("\\+");
                int[] sumArray = new int[tempArray.length];
                for(int j = 0; j < tempArray.length; j++){
                    sumArray[j] = Integer.parseInt(tempArray[j]);
                }

                int sum = Arrays.stream(sumArray).sum();
                numberArray[i] = sum;
            }
            else{
                numberArray[i] = Integer.parseInt(inputArray[i]);
            }
        }

        int result = numberArray[0];
        for(int i = 1; i < numberArray.length; i++){
            result -= numberArray[i];
        }

        bw.write(result + "\n");
        bw.flush();
        bw.close();
        br.close();
    }
}

 

현재 상황에서 최적의 해답을 선택한다. -> 최대한 큰 숫자를 뺄셈에 활용하기 위해 현재 탐색에서 + 기호가 발견될 경우 현재 탐색중인 문자열에 포함되어 있는 숫자들끼리 모두 더해서 뺄셈 배열에 저장해준다.

선택된 해답이 조건을 만족하는지 검사한다. -> 덧셈, 또는 따로 저장된 숫자들끼리 뺄셈을 수행해 구할 수 있는 최소값에 근접한 값을 찾아낸다.

 

위의 과정을 통해 구할 수 있는 최소값에 근접한 값을 찾았으므로 그리디 알고리즘에 해당된다.