문제 해석
- 문제를 간략히 설명하자면, 주어진 각각의 연산자(+, -, x, /)의 개수를 모두 사용하고, 주어진 숫자와 연산자를 연결하여, 최댓값과 최솟값을 구하면 되는 문제이다.
- 예를 들어, 아래와 같이 주어졌다고 하자.
5 -> 주어지는 숫자의 개수
1 2 3 4 5 -> 주어지는 숫자
1 1 2 0 -> 연산자의 각각의 개수 (+ : 1개, - : 1개, x : 2개, / : 0개)
/* 최댓값 구하기 */
5x4x3+2-1 = 61
/* 최솟값 구하기 */
1+2-5x4x3 => -57
- 핵심 로직은 아래와 같다.
- 위의 그림 처럼 숫자와 연산자를 묶어 dfs 탐색을 한다.
코드
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.StringTokenizer;
public class Main {
public static int maxValue = Integer.MIN_VALUE;
public static int minValue = Integer.MAX_VALUE;
public static int[] operator = new int[4];
public static int[] number;
public static int N;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
number = new int[N];
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int i = 0; i < N; i++) {
number[i] = Integer.parseInt(st.nextToken());
}
st = new StringTokenizer(br.readLine(), " ");
for (int i = 0; i < 4; i++) {
operator[i] = Integer.parseInt(st.nextToken());
}
br.close();
solution(number[0], 1);
System.out.println(maxValue);
System.out.println(minValue);
}
public static void solution(int num, int index) {
if (index == N) {
maxValue = Math.max(maxValue, num);
minValue = Math.min(minValue, num);
return;
}
for (int i = 0; i < 4; i++) {
if (operator[i] > 0) {
operator[i]--;
switch (i) {
case 0:
solution(num + number[index], index + 1);
break;
case 1:
solution(num - number[index], index + 1);
break;
case 2:
solution(num * number[index], index + 1);
break;
case 3:
solution(num / number[index], index + 1);
break;
}
operator[i]++;
}
}
}
}
결과
느낀 점
- 백트래킹/dfs에 대해 계속 문제를 풀고 있는데 알다가도 갑자기 까먹고, 아직 익숙하진 않아서 앞으로 더 봐야할 알고리즘 같다.