Coding Test/백준

[백준] 14888 연산자 끼워넣기 - 자바

lsh2613 2023. 7. 12. 19:23

https://www.acmicpc.net/problem/14888

 

14888번: 연산자 끼워넣기

첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱

www.acmicpc.net

 

문제 풀이

 

입력 조건과 시간제한을 보면 꽤나 여유롭게 풀 수 있는 문제로 완전탐색을 진행하여 풀 것이다. dfs, bfs 뭐든 상관 없지만 웬만하면 재귀를 이용한 dfs가 더욱 간단한 것 같다.

완전탐색 구현 및 종료조건만 잘 정한다면 비교적 쉽게 구현 가능하다.

다음 코드가 왜 완전탐색인지 이해가 안 간다면 작은 값의 N으로 샘플을 직접 손으로 따라가거나 디버깅을 통해 확인해보면 쉽게 이해할 수 있을 것이다.

 

여기서 종료 조건은 연산자의 개수 즉 N-1번으로 본인은 dfs(1)부터 시작하여 N이 됐을 때까지 진행하였다.

참고!
6개의 수로 이루어진 수열이 1, 2, 3, 4, 5, 6이고, 주어진 연산자가 덧셈(+) 2개, 뺄셈(-) 1개, 곱셈(×) 1개, 나눗셈(÷) 1개인 경우에는 총 60가지의 식을 가진다고 하는데 여기서 60이 나온 이유는 숫자는 그대로 둔다 했고 중간에 총 5개의 연산을 껴넣으며 순서가 존재하고 중복이 있다. 즉, 증복순열로 5!/2! = 60이 나온 것이다.
알고리즘을 설계하고 문제를 푸는 데에는 지장 없으니 참고만 하고 넘어가자.

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

    public static int n;
    public static int[] nums;
    public static int plus, minus, mul, div;
    public static int min = Integer.MAX_VALUE;
    public static int max = Integer.MIN_VALUE;

    // dfs를 통한 완전탐색
    public static void dfs(int i, int result) {
        // 모든 연산자를 다 사용한 경우, 최솟값과 최댓값 업데이트
        if (i == n) {
            min = Math.min(min, result);
            max = Math.max(max, result);
        }
        else {
            // 각 연산자에 대하여 재귀적으로 수행
            if (plus > 0) {
                plus -= 1;
                dfs(i + 1, result + nums[i]);
                plus += 1;
            }
            if (minus > 0) {
                minus -= 1;
                dfs(i + 1, result - nums[i]);
                minus += 1;
            }
            if (mul > 0) {
                mul -= 1;
                dfs(i + 1, result * nums[i]);
                mul += 1;
            }
            if (div > 0) {
                div -= 1;
                dfs(i + 1, result / nums[i]);
                div += 1;
            }
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        n = Integer.parseInt(br.readLine());
        nums = Arrays.stream(br.readLine().split(" "))
                .mapToInt(Integer::parseInt)
                .toArray();
        StringTokenizer st = new StringTokenizer(br.readLine());

        plus = Integer.parseInt(st.nextToken());
        minus = Integer.parseInt(st.nextToken());
        mul = Integer.parseInt(st.nextToken());
        div = Integer.parseInt(st.nextToken());

        // 첫 번째 숫자를 시작으로 dfs 완전탐색 실행
        dfs(1, nums[0]);

        System.out.println(max);
        System.out.println(min);
    }
}