(Java) 프로그래머스 18111번 - N으로 표현

코딩너구리·2026년 5월 6일

코딩 문제 풀이

목록 보기
265/266

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

문제

> 아래와 같이 5와 사칙연산만으로 12를 표현할 수 있습니다.

12 = 5 + 5 + (5 / 5) + (5 / 5)
12 = 55 / 5 + 5 / 5
12 = (55 + 5) / 5

> 5를 사용한 횟수는 각각 6,5,4 입니다. 
> 그리고 이중 가장 작은 경우는 4입니다.
> 이처럼 숫자 N과 number가 주어질 때,
N과 사칙연산만 사용해서 표현 할 수 있는 방법 중 N 사용횟수의 최솟값을 return 하도록 solution 함수를 작성하세요.

접근

dp를 사용하는데 이때, dp의 인덱스 기준을 해당 N을 사용한 횟수로 두고 가야한다.
그리고 이 dp(i)에 대한 원소들은 N을 i번 썼을 때, 만들 수 있는 수들을 가진다.
또 모든 경우를 따지다 보면 겹치는 수가 많기 때문에 Set을 사용하여 겹치는 수를 처리한다.
8보다 크면 -1을 출력하므로 8까지의 모든 경우를 구한뒤 1부터 8까지 contains로 원하는 number을 찾으면 해당 i를 출력한다.

문제해결

> dp를 동적배열로 선언하는데 겹치는 수의 처리를 위해 Integer형 Set타입으로 선언한다.
> 초기 설정으로 각 dp인덱스에 Set을 생성해주고 i에 따라 5, 55, 555...를 위해 초기값으로 넣어준다.
> 이제 2부터 8까지의 경우를 구해주기 위해 반복한다.
> 내부에서 1부터 i-1까지 반복을 하며 해당 i의 경우를 위한 모든 경우를 따져준다.
> 예를들어 i가 4라면 t가 1,2,3이고 이에따라 dp(1)과 dp(3), dp(2)와 do(2), dp(3)과 dp(1)로 dp(4)의 경우를 생성한다.
> 경우는 사칙연산으로 만드는데 나누기 연산은 zerodivision문제를 방지하기위해 이를 처리한다.
> 모든 경우를 구했으므로 1부터 8까지 dp를 돌며 해당 i번 째에 원하는 number가 있는지 contains로 확인한다.
> 있다면 i를 반환하고 끝내며, 없으면 8을 넘어가므로 -1을 반환한다.

코드

import java.util.*;
import java.lang.*;

class Solution {
    public int solution(int N, int number) {
        List<Set<Integer>> dp = new ArrayList<>();
        
        for(int i = 0; i < 9; i++) {
            dp.add(new HashSet<>());
            if(i < 1) continue;
            int tmp = N;
            for(int t = 0; t < i-1; t++) tmp = tmp * 10 + N;
            dp.get(i).add(tmp);
        }
        for(int i = 2; i < 9; i++) {
            for(int t = 1; t <= i-1; t++) {
                Set<Integer> a = dp.get(t);
                Set<Integer> b = dp.get(i-t);
                for(Integer A : a) {
                    for(Integer B : b) {
                        dp.get(i).add(A + B);
                        dp.get(i).add(A - B);
                        dp.get(i).add(A * B);
                        if(B != 0) dp.get(i).add(A / B);
                    }
                }
            }
        }
        for(int i = 1; i < 9; i++) {
            if(dp.get(i).contains(number)) return i;
        }
        return -1;
    }
}

후기

자료구조를 사용하는 부분이 굉장히 어렸웠고 반복문이 깊어지며 헷갈려서 힘들었다.

0개의 댓글