[백준] 모노디지털 표현 (2287, Java)
2022. 8. 21. 10:01ㆍ코딩테스트/백준
문제
몇 개의 숫자 K(K는 1, 2, …, 9중 하나)와 사칙 연산(덧셈, 뺄셈, 곱셈, 나눗셈)만을 사용하여 어떤 자연수 X를 수식으로 표현한 것을 X의 K-표현이라 부른다. 수식에는 괄호가 포함될 수 있으며, 나눗셈은 나눈 몫만을 취한다.
예를 들어 12의 5-표현을 몇 개 써 보면 5+5+(5/5)+(5/5), 55/5+5/5, (55+5)/5 등이 있다. K-표현의 길이를 사용한 K의 개수라 하면, 각각의 길이는 6, 5, 4가 된다.
K가 주어졌을 때, 어떤 자연수의 K-표현 중 가장 짧은 길이를 알아보려 한다.
입력
첫째 줄에 K가 주어진다. 다음 줄에는 표현 식을 찾을 수의 개수 n(1 ≤ n ≤ 1,000)이 주어진다. 다음 줄에는 K-표현 중 가장 짧은 길이를 알아보려 하는 자연수 a(1 ≤ a ≤ 32,000)가 주어진다.
출력
입력되는 순서대로 K-표현의 최소 길이를 n개의 줄에 출력한다. 만약 K-표현의 최소 길이가 8보다 크다면 “NO"를 출력한다.
예제 입력 1
5
2
12
31168
예제 출력 1
4
NO
- k값과 이를 통해 만들어야 하는 값인 a를 가지고 8개 안으로 만들 수 있다면 그 수를 리턴하고 그렇지 않다면 NO를 출력해야 하는 문제이다.
- 생각해줄 수 있는 것은 수를 만들 때 사용할 수 있는 최대 개수가 8개이기 때문에 이를 집합(Set)의 배열로 만들어준 뒤 base value로부터 bottom-up 방식의 dp로 풀어나갈 수 있지 않을까 하는 것이다.
- 위에서 언급한 base value 값은 k, kk, kkk, kkkk.... 식의 값들이고 이는 k는 1번째 index, kk는 2번째 index의 집합(그 뒤는 생략)에 넣어주었다.
- 한 개로 만들 수 있는 값은 k 하나로 자명하기 때문에 이는 고려하지 않고 그 뒤에 2개부터 8개까지 루프를 돌면서 만일 값이 4일 때 (1st idx,3rd idx),(2nd idx,2nd idx),(3rd idx,1st idx)의 수 조합을 통하여 사칙연산을 해준 뒤 Set에 넣어주었다. (물론, 결과값이 기준치를 넘어가거나 그 밑으로 내려가는 경우는 제외하였다.)
- 마지막으로, n개의 a 값을 위에서 구한 set의 집합을 쭉 돌면서 존재하는 경우는 해당 index를 리턴하고 그렇지 않다면 NO를 리턴하는 식으로 문제를 풀이하였다.
import java.util.*;
import java.io.*;
public class Main {
static int k, n;
static boolean checked[];
static Set<Integer>[] group;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
k = stoi(br.readLine());
n = stoi(br.readLine());
group = new Set[9];
checked = new boolean[1000000];
for (int i = 1; i <= 8; ++i) {
group[i] = new HashSet<>();
}
int num = k;
for (int i = 1; i <= 6; ++i) {
checked[num] = true;
group[i].add(num);
num *= 10;
num += k;
}
for (int i = 2; i <= 8; ++i) {
for (int j = 1; j < i; ++j) {
for (int x : group[j]) {
for (int y : group[i-j]) {
if (x + y < 1000000 && !checked[x+y]) {
checked[x+y] = true;
group[i].add(x+y);
}
if (y != 0 && x / y > 0 && !checked[x/y]) {
checked[x/y] = true;
group[i].add(x/y);
}
if (x - y >= 0 && !checked[x-y]) {
checked[x-y] = true;
group[i].add(x-y);
}
if (x * y < 1000000 && !checked[x*y]) {
checked[x*y] = true;
group[i].add(x*y);
}
}
}
}
}
for (int i = 0; i < n; ++i) {
int a = stoi(br.readLine());
if (!checked[a]) {
sb.append("NO\n");
continue;
}
for (int k = 1; k <= 8; ++k) {
if (group[k].contains(a)) {
sb.append(k + "\n");
break;
}
}
}
System.out.print(sb);
br.close();
}
static int stoi(String input) {
return Integer.parseInt(input);
}
}
'코딩테스트 > 백준' 카테고리의 다른 글
[백준] 통신망 분할 (17398, Java) (0) | 2022.08.22 |
---|