문제 링크: https://www.acmicpc.net/problem/3687

 

3687번: 성냥개비

각 테스트 케이스에 대해서 입력으로 주어진 성냥개비를 모두 사용해서 만들 수 있는 가장 작은 수와 가장 큰 수를 출력한다. 두 숫자는 모두 양수이어야 하고, 숫자는 0으로 시작할 수 없다. 

www.acmicpc.net

▶문제

성냥개비는 숫자를 나타내기에 아주 이상적인 도구이다. 보통 십진수를 성냥개비로 표현하는 방법은 다음과 같다.

성냥개비의 개수가 주어졌을 때, 성냥개비를 모두 사용해서 만들 수 있는 가장 작은 수와 큰 수를 찾는 프로그램을 작성하시오.


▶입력

첫째 줄에 테스트 케이스의 개수가 주어진다. 테스트 케이스는 최대 100개이다. 각 테스트 케이스는 한 줄로 이루어져 있고, 성냥개비의 개수 n이 주어진다. (2 ≤ n ≤ 100)


▶출력

각 테스트 케이스에 대해서 입력으로 주어진 성냥개비를 모두 사용해서 만들 수 있는 가장 작은 수와 가장 큰 수를 출력한다. 두 숫자는 모두 양수이어야 하고, 숫자는 0으로 시작할 수 없다.


▶해설

DP 문제입니다. 조건을 살펴보겠습니다.

 

1. 각각의 숫자를 만드는데 성냥개비의 개수가 정해져있다.

2. 숫자는 0으로 시작할 수 없다.

3. 가장 작은 수와 가장 큰 수를 만들어라. 

 

0~9까지 숫자를 만드는데 필요한 성냥개비의 수는 아래와 같습니다.

2개 = 1

3개 = 7

4개 = 4

5개 = 2,3,5

6개 = 0,6,9

7개 = 8

 

가장 큰 수를 만드는 것은 쉽게 구할 수 있습니다. 수의 자릿수를 크게 하면 됩니다.

 

1. 주어진 수가 2로 나눠 떨어지다면

-> 몫의 값만큼 1인 String 생성

2. 주어진 수가 2로 나눠 떨어지지 않는다면

-> "7" + 주어진 수 - 3 / 2 몫만큼 1인 String 생성

if(n%2==0){
    sb.append(convertMax(n/2));
}
else{
    sb.append("7").append(convertMax((n-3)/2));
}
private static String convertMax(int n){
    StringBuilder sb = new StringBuilder();
    for(int i=0; i<n; i++){
        sb.append("1");
    }
    return sb.toString();
}

이제 작은 수를 만들어야 합니다. 성냥개비가 6개가 주어졌을 때는 0으로 시작할 수 없으므로 6개로 만들 수 있는 수중 두 번째로 작은 수인 6으로 초기화합니다. 기본 성냥개비의 범위는 2~7이므로 반복문을 간단하게 하기 위해 8개일 때까지 구해줍니다.

dp[2]=1;
dp[3]=7;
dp[4]=4;
dp[5]=2;
dp[6]=6;
dp[7]=8;
dp[8]=10;

성냥개비가 9개일 때부터 순차적으로 구하면 됩니다. 

기본 성냥개비의 범위 = 2~7 각각의 값{1,7,4,2,0,8} -> arr []

성냥개비가 9개일 때

String.valueOf(dp [9-2]) + String.valueOf(arr [0]);

String.valueOf(dp [9-3]) + String.valueOf(arr [1]);

...

이런 식으로 구성됩니다. 그랬을 때 가장 작은 값을 넣어주면 됩니다.

for(int i=9; i<=100; i++){
    for(int j=2; j<=7; j++){
        String temp = String.valueOf(dp[i-j])+String.valueOf(arr[j-2]);
        dp[i] = Math.min(Long.parseLong(temp),dp[i]);
    }
}

전체 코드

import java.io.*;
import java.util.*;

public class Main {
    static long [] dp;
    static int [] arr= {1,7,4,2,0,8};
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int t = Integer.parseInt(br.readLine());

        dp = new long[101];

        Arrays.fill(dp,Long.MAX_VALUE);

        dp[2]=1;
        dp[3]=7;
        dp[4]=4;
        dp[5]=2;
        dp[6]=6;
        dp[7]=8;
        dp[8]=10;

        StringBuilder sb;


        for(int i=9; i<=100; i++){
            for(int j=2; j<=7; j++){
                String temp = String.valueOf(dp[i-j])+String.valueOf(arr[j-2]);
                dp[i] = Math.min(Long.parseLong(temp),dp[i]);
            }
        }

        for(int i=0; i<t; i++){
            int n = Integer.parseInt(br.readLine());
            sb = new StringBuilder();

            sb.append(dp[n]).append(" ");
            if(n%2==0){
                sb.append(convertMax(n/2));
            }
            else{
                sb.append("7").append(convertMax((n-3)/2));
            }

            System.out.println(sb.toString());
        }
    }

    private static String convertMax(int n){
        StringBuilder sb = new StringBuilder();
        for(int i=0; i<n; i++){
            sb.append("1");
        }
        return sb.toString();
    }
}