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
에 다음 인덱스의 수를 연산하고 넘겨줘야하므로 재귀함수의val
에val (연산자) 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]++;
}
}
}
}