본문 바로가기
PS 문제 풀이/Baekjoon

[BOJ] 백준 14888 연산자 끼워넣기

by 까망 하르방 2021. 2. 21.
반응형

출처: https://www.acmicpc.net/problem/14888

 Input 

6

1 2 3 4 5 6

2 1 1 1

 

 Output 

54

-24

수와 수 사이에 연산자를 임의로 넣어서 식의 결과가 최대 최소인 것을 구하시오.

※ 연산자의 순서는 바꿀 수 있지만 주어진 수의 순서를 바꿀수 없습니다.

    ex) 1-2÷3+4+5*6 = 54 

    ex) 1*2+3÷4-5×6 = -24

* 사칙연산 우선순위를 무시하고 앞에서부터 진행합니다.

    따라서, 0으로 나누는 경우는 없습니다. ex) 5 ÷ 0 (x)

* 나눗셈의 경우 몫만 취합니다. (분모가 음수인 경우는 없습니다.)

    {(음수)÷(양수)}의 경우 음수를 양수로 바꿔 계산한 후 그 몫을 음수로 바꿉니다.

 

구현 사항

- 연산자를 완전탐색하여 가능한 경우의 수를 구합니다. ← 중복 없는 순열

- 모든 경우의 수 중 최댓값과 최솟값을 구합니다. 


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


public class Main {
    
    static List<String> operatorList;
    static List<Integer> operand;
    static int min =Integer.MAX_VALUE, max=Integer.MIN_VALUE;
    
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new  InputStreamReader(System.in));
           BufferedWriter bw = new BufferedWriter(new  OutputStreamWriter(System.out));

        int N = Integer.parseInt(br.readLine());
        
        // 피연산자를 저장해둔다.
        StringTokenizer st = new StringTokenizer(br.readLine());
        operand = new ArrayList<>();
        for(int i=0; i<N; i++) {
            operand.add(Integer.parseInt(st.nextToken()));
        }
        
        int[] operator = new int[4];
        operatorList = new ArrayList<>();
        
        // 입력받은 연산자개수 만큼 해당 연산자를 우선 리스트에 보관한다.
        String[] opr = {"+", "-", "*", "/"};
        st = new StringTokenizer(br.readLine());
        for(int i=0; i<4; i++) {
            operator[i] = Integer.parseInt(st.nextToken());
            while(operator[i]-- > 0) {
                // 개수만큼 해당 되는 연산자 기호를 넣는다.
                operatorList.add(opr[i]);
            }
        }
        // 순열을 위한 방문 표시
        boolean[] visited = new boolean[operatorList.size()];
        List<String> list = new ArrayList<>();
        
        // 연산자를 순열로 재구성하고 계산결과를 구한다.
        permutation(list, visited);
        
        // 정답 출력
        bw.write(max + "\n");
        bw.write(min + "\n");
        bw.flush(); bw.close();
    }

    private static void permutation(List<String> list, boolean[] visited) {
        if(list.size() == operatorList.size()) {
            
            int result = calculate(list);
            min = min > result ? result : min;
            max = max < result ? result : max;
            return;
        }
        
        for(int i=0; i<operatorList.size(); i++) {
            // 아직 사용하지 원소라면
            if(!visited[i]) {
                // 방문 표시
                visited[i] = true; list.add(operatorList.get(i));
                permutation(list, visited);                
                visited[i] = false; list.remove(list.size()-1);
            }
        }
        
    }

    private static int calculate(List<String> list) {
        // 제일 처음 피연산자로 초기화 해둔다.
        int result = operand.get(0);
        // 연산자와 피연산자의 개수가 맞지 않은 경우는 없으므로 차례대로 연산의 겨로가를 구한다.
        for(int i=1; i<operand.size(); i++) {
            int target = operand.get(i);
            String operator = list.get(i-1);
            if(operator.equals("+")) result += target;
            else if(operator.equals("-")) result -= target;
            else if(operator.equals("*")) result *= target;
            else if(operator.equals("/")) {
                if(result < 0) { // 분자가 음수인 경우
                    result = Math.abs(result) / target;
                    result *= -1;
                }else {
                    result = result / target;
                }
            }
        }
        return result;
    }
}

 

반응형

'PS 문제 풀이 > Baekjoon' 카테고리의 다른 글

[BOJ] 백준 14890 경사로  (0) 2021.02.21
[BOJ] 백준 14889 스타트와 링크  (0) 2021.02.21
[BOJ] 백준 19237 어른상어  (0) 2021.02.21
[BOJ] 백준 14501 퇴사  (0) 2021.02.21
[BOJ] 백준 14500 테트로미노  (0) 2021.02.21

댓글