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

진예·2023년 12월 8일
0

Baekjoon : JAVA

목록 보기
68/76
post-thumbnail

📌 문제

[14888] 연산자 끼워넣기

N개의 수로 이루어진 수열 A1, A2, ..., AN이 주어진다. 또, 수와 수 사이에 끼워넣을 수 있는 N-1개의 연산자가 주어진다. 연산자는 덧셈(+), 뺄셈(-), 곱셈(×), 나눗셈(÷)으로만 이루어져 있다.

우리는 수와 수 사이에 연산자를 하나씩 넣어서, 수식을 하나 만들 수 있다. 이때, 주어진 수의 순서를 바꾸면 안 된다.

예를 들어, 6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 2개, 뺄셈(-) 1개, 곱셈(×) 1개, 나눗셈(÷) 1개인 경우에는 총 60가지의 식을 만들 수 있다. 예를 들어, 아래와 같은 식을 만들 수 있다.

1+2+3-4×5÷6
1÷2+3+4-5×6
1+2÷3×4-5+6
1÷2×3-4+5+6

식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 진행해야 한다. 또, 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. 즉, 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다. 이에 따라서, 위의 식 4개의 결과를 계산해보면 아래와 같다.

1+2+3-4×5÷6 = 1
1÷2+3+4-5×6 = 12
1+2÷3×4-5+6 = 5
1÷2×3-4+5+6 = 7

N개의 수와 N-1개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.

⬇️ 입력

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다.

⬆️ 출력

첫째 줄에 만들 수 있는 식의 결과의 최댓값을, 둘째 줄에는 최솟값을 출력한다. 연산자를 어떻게 끼워넣어도 항상 -10억보다 크거나 같고, 10억보다 작거나 같다.

✔️ 힌트

세 번째 예제의 경우에 다음과 같은 식이 최댓값/최솟값이 나온다.

  • 최댓값: 1-2÷3+4+5×6
  • 최솟값: 1+2+3÷4-5×6

💡 코드

N개의 수를 크기가 n인 num[]에 차례대로 저장하고, 연산자의 개수를 덧셈, 뺄셈, 곱셈, 나눗셈의 순서로 op[]에 저장한 후 cal()을 호출하여 연산자를 끼워넣는다.

메서드 cal(val, idx)이번 단계에서 계산할 숫자 val다음 인덱스 idx를 매개변수로 받는다. main 메서드에서 첫번째 숫자인 num[0]과 다음 인덱스인 1을 입력받아서 시작한다.

이후 for문을 통해 각 연산자의 개수에 따라 연산자를 끼워넣는데, 이 때 연산자가 하나라도 있어야 가능하므로 op[i] > 0인 경우에만 연산자를 끼워넣는다.

연산자가 하나라도 있는 경우, 연산자를 사용해야 하므로 op[i]의 값을 감소시키고 switch~case문을 통해 각 인덱스에 해당하는 연산을 수행한다. (+, -, *, / 순서) 이 때, 현재 숫자인 val다음 인덱스의 수를 연산하고 넘겨줘야하므로 재귀함수의 valval (연산자) num[idx+1]를 넘겨준다. 재귀함수를 통해 다음 인덱스로 넘어가서 연산을 수행하다가 idx = n이 되면 최종 결과값이 최댓값인지, 최솟값인지 판별하고 재귀를 종료한다. 재귀를 마치고 돌아오면 사용했던 연산자의 개수를 다시 증가시켜줘야 한다.

import java.io.*;
import java.util.*;
public class Main {
	
	static int[] num;
	static int n;
	
	static int[] op = new int[4];
	static int min = Integer.MAX_VALUE;
	static int max = Integer.MIN_VALUE;
	static int result = 0;
	
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
		
		n = Integer.parseInt(br.readLine());
		num = new int[n];
		
		StringTokenizer st = new StringTokenizer(br.readLine());
		for(int i=0;i<n;i++) {
			num[i] = Integer.parseInt(st.nextToken());
		}
		
		st = new StringTokenizer(br.readLine());
		for(int i=0;i<4;i++) { // + - * /
			op[i] = Integer.parseInt(st.nextToken());
		}
		
		cal(num[0], 1);
		bw.write(max + "\n" + min);;
		
		br.close();
		bw.close();
	}
	
	static void cal(int val, int idx) {
		
		if(idx == n) {
			max = Math.max(val, max);
			min = Math.min(val, min);
			return;
		}
		
		for(int i=0;i<4;i++) {
			if(op[i] > 0) {
				
				op[i]--;
				
				switch(i) {
					case 0 : cal(val + num[idx], idx+1); break;
					case 1 : cal(val - num[idx], idx+1); break;
					case 2 : cal(val * num[idx], idx+1); break;
					case 3 : cal(val / num[idx], idx+1); break;
				}
				
				op[i]++;
			}
		}
	}
}

profile
백엔드 개발자👩🏻‍💻가 되고 싶다

0개의 댓글