Baekjoon

14888, 15685 - 연산자 끼워넣기 (1), (2)

kjy0349 2022. 5. 26. 15:52

같은 코드로도 두 문제를 모두 통과 할 수 있어서 묶어서 올리게 되었다.

생각했던 것들

일반적인 순열 문제라고 생각해서, 처음에 Input으로 들어오는 연산자들의 개수만큼 ArrayList에 넣어 둔 후, 순열로 돌면서 선택하는 방법으로 구현했다.

ex) 연산자의 개수가 각각 + : 1, - : 2, * : 3, / : 4 개일 경우, 연산자 각각의 인덱스를 이용해 모두 삽입
ArrayList -> {0, 1, 1, 2, 2, 2}
와 같이 만들어두고 연산을 진행했다. 해당 코드로 연산자 끼워넣기 (1)을 통과하고나서, (2)도 똑같은 방식인것 같아 같은 코드를 넣었더니..

오랜만에 보는 시간 초과 메세지가 보였다.

틀린 이유

틀린 이유는 생각보다 간단했다. 위의 코드에서, + 연산자를 두 번째로 선택한 경우를 생각해보자.

1 + 2 + 3 4 5

(+ : 3, - : 2, * : 1, / : 2)

위의 코드에서는, 두 번째로 선택한 +가 + 연산자들 중 몇 번째 + 연산자인지에 따라서 다른 경우로 취급한다.

 

이 문제에서 중요한것은 연산자를 숫자들 사이에 있는 어떤 자리에 연산자를 넣을것인가이지, 지금 선택한 연산자가 해당 연산자들 중 몇 번째 연산자인지가 아니다. 해당 위치에 + 연산자를 선택했다면, 이 연산자가 몇 번째로 나온 + 인지는 전혀 상관이 없다는 것이다.

 

따라서 위의 코드에서 연산자의 개수만큼 ArrayList에 넣어 순열로 돌리는것이 아닌, 연산자들의 개수를 가지고 있는 배열에서 하나의 연산자를 선택 할 때 마다 개수를 줄이는 방식으로 구현을 바꾸었다.

package backjoon;
import java.io.*;
import java.util.StringTokenizer;

public class P_15658 {
    static int MIN = Integer.MAX_VALUE;
    static int MAX = Integer.MIN_VALUE;
    static int[] ops;
    static int[] nums;

    public static int calc(int sub_sum, int count, int operator) {
        // 0 : + , 1 : -, 2 : *, 3 : /
        int result = 0;
        switch (operator) {
            case 0:
                result = sub_sum + nums[count + 1];
                break;
            case 1:
                result = sub_sum - nums[count + 1];
                break;
            case 2:
                result = sub_sum * nums[count + 1];
                break;
            case 3:
                result = sub_sum / nums[count + 1];
        }
        return result;
    }

    public static void perm(int count, int N, int sub_sum) {
        if (count == N - 1) {
            if (sub_sum > MAX) MAX = sub_sum;
            if (sub_sum < MIN) MIN = sub_sum;
        } else {
            for (int i = 0; i < 4; i++) {
                if (ops[i] > 0) {
                    ops[i]--;
                    perm(count + 1, N, calc(sub_sum, count, i));
                    ops[i]++;
                }
            }
        }
    }

    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        int N = Integer.parseInt(br.readLine());
        StringTokenizer st = new StringTokenizer(br.readLine());
        nums = new int[N];
        for (int i = 0; i < N; i++) nums[i] = Integer.parseInt(st.nextToken());
        ops = new int[4];
        st = new StringTokenizer(br.readLine());
        for (int i = 0; i < 4; i++) ops[i] = Integer.parseInt(st.nextToken());
        perm(0, N, nums[0]);
        bw.write(MAX + "\n");
        bw.write(MIN + "\n");
        bw.flush();
    }
}