반응형
백준 14888. 연산자 끼워넣기와 똑같은 문제입니다. 저는 연산자 끼워넣기 문제를 순열을 이용하여서 연산자들을 줄세워서 나올 수 있는 모든 경우의 수를 확인했습니다. 그리고 그 때마다 숫자 계산을 하여 최댓값과 최솟값을 구했는데, 이번문제도 처음엔 그렇게 풀려고 시도해봤는데 시간초과가 발생했습니다.
극단적인 예로 '+' 연산자가 10개가 있으면 실제로는 한 번만 계산하면 되지만, 10!의 순열을 계산하면서 거기에서 시간초과가 발생한 것 같습니다. 중복된 연산자를 처리하기에 순열을 이용하면 비효율적입니다.
그래서 이번 문제는 재귀를 통한 완전탐색으로 해결했는데, 코드를 보면 쉽게 이해할 수 있기 때문에 문제풀이 순서는 생략하려고 합니다. 이러한 패턴의 문제들이 많은것 같은데 풀이 방법을 숙지해야겠고, 백준의 문제도 한번 똑같은 방법으로 풀어서 시간을 비교해봐야할 것 같습니다.
import java.util.Scanner;
public class Solution {
static int N, maxVal, minVal;
static int[] operator, operand;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
for(int tc=1; tc<=T; tc++) {
N = sc.nextInt();
operator = new int[4];
operand = new int[N];
for(int i=0; i<4; i++) operator[i] = sc.nextInt();
for(int i=0; i<N; i++) operand[i] = sc.nextInt();
maxVal = Integer.MIN_VALUE;
minVal = Integer.MAX_VALUE;
recur(1, operand[0]);
System.out.println("#" + tc + " " + (maxVal-minVal));
}
}
public static void recur(int depth, int result) {
if(depth >= N) {
maxVal = Math.max(result, maxVal);
minVal = Math.min(result, minVal);
return;
}
for(int i=0; i<4; i++) {
if(operator[i] <= 0) continue;
operator[i]--;
switch(i) {
case 0:
recur(depth+1, result + operand[depth]);
break;
case 1:
recur(depth+1, result - operand[depth]);
break;
case 2:
recur(depth+1, result * operand[depth]);
break;
case 3:
recur(depth+1, result / operand[depth]);
break;
}
operator[i]++;
}
}
}
반응형
'알고리즘 > SW 역량 테스트' 카테고리의 다른 글
[백준] 17822. 원판 돌리기 (0) | 2020.04.28 |
---|---|
[백준] 17837. 새로운 게임2 (0) | 2020.04.24 |
[백준] 14500. 테트로미노 (0) | 2020.03.03 |
[백준] 14890. 경사로 (0) | 2020.03.02 |
[백준] 17143. 낚시왕 (0) | 2020.02.19 |