https://www.acmicpc.net/problem/14888
사용 알고리즘
- 백트래킹
- 재귀
풀이
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class Main {
static int n;
static int [] nums;
static int [] cal = new int [4];
static int max = Integer.MIN_VALUE;
static int min = Integer.MAX_VALUE;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
n = Integer.parseInt(br.readLine());
nums = new int [n];
StringTokenizer st = new StringTokenizer(br.readLine());
for(int i = 0; i < n; i++){
nums[i] = Integer.parseInt(st.nextToken());
}
st = new StringTokenizer(br.readLine());
for(int i = 0; i < 4; i++){
cal[i] = Integer.parseInt(st.nextToken());
}
// 1. 계산 배열을 순회하며
dfs(nums[0], 1);
System.out.println(max);
System.out.println(min);
}
private static void dfs(int num, int depth) {
if (depth == n) {
max = Math.max(max, num);
min = Math.min(min, num);
return;
}
for(int i = 0; i < 4; i++){
if (cal[i] > 0) {
cal[i]--;
switch(i) {
case 0: dfs(num + nums[depth] , depth + 1); break;
case 1: dfs(num - nums[depth] , depth + 1); break;
case 2: dfs(num * nums[depth] , depth + 1); break;
case 3: dfs(num / nums[depth] , depth + 1); break;
}
cal[i]++;
}
}
}
}
회고
백트래킹에 어느정도 익숙해졌다고 생각해졌지만 쉽지 않았다. 주어진 연산자의 개수에 따라서 재귀를 돌리면 되겠다는 인지했으나 코드로 구현하는데 어려움을 겪었다.
대략적인 풀이는 연산자 배열을 순회하며 현재 값인 num의 값을 업데이트 해주며 depth를 1 증가시킨다.
재귀의 종료 조건은 depth가 n일때고, 이 때 min, max 변수를 두어서 각 값을 업데이트 해주면 된다.
- 5/11 추가 내용
문제를 다시 풀어보면서, dfs(arr[0], 0)일 때 결과값이 정상적으로 출력되지 않는 것을 확인했다.
2
5 6
0 0 1 0
가 예제로 주어진 경우
30
30
가 각각 결과값으로 나와야 하지만, 두번째 depth 값을 0으로 설정한 경우 25,25가 출력되었다.
왜 그런가 유심히 살펴보니, 로직 내에서 num[0] * num[0], 즉 자기 자신을 곱한 결과를 리턴하기 때문에 생긴 문제였다.
배열의 시작값은 arr[0]이고, depth는 배열의 인덱스를 의미하므로 depth는 1이 되어야 한다.
'Algorithm > 백준' 카테고리의 다른 글
[백준] Silver II. 부분수열의 합 (0) | 2024.05.12 |
---|---|
[백준] Gold IV. N-Queen (0) | 2024.05.12 |
[백준] Gold 4 카드 정렬하기 (0) | 2024.05.07 |
[백준] Silver 1 절댓값 힙 (0) | 2024.05.07 |
[백준] Silver 3. N과 M(9) (0) | 2024.04.24 |