ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 14888, 15685 - 연산자 끼워넣기 (1), (2)
    Baekjoon 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();
        }
    }
    

    'Baekjoon' 카테고리의 다른 글

    2580 - 스도쿠  (0) 2022.05.30
    16197 - 두 동전  (0) 2022.05.28
    20055 - 컨베이어 벨트 위의 로봇  (0) 2022.05.24
    1261 - 알고 스팟  (0) 2022.04.22
    13549 - 숨바꼭질 3  (0) 2022.04.22
Designed by Tistory.