View
📚 문제
못생긴 수란 오직 2, 3, 5만을 소인수로 가지는 수를 의미합니다. 다시 말해 오직 2, 3, 5를 약수로 가지는 합성수를 의미합니다. 1은 못생긴 수라고 가정합니다. 따라서 못생긴 수들은 {1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, ...} 순으로 이어지게 됩니다. 이때 n번째 못생긴 수를 찾는 프로그램을 작성하세요. 예를 들어 11번째 못생긴 수는 15입니다.
예제 입력 | 예제 출력 |
10 | 12 |
4 | 4 |
📝 문제 해결
이 문제는 가능한 못생긴 수를 앞에서부터 하나씩 찾는 방법으로 해결할 수 있다. 못생긴 수들은 [1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, …]와 같이 끊임없이 존재한다. 이때 못생긴 수에 2, 3 혹은 5를 곱한 수 또한 ‘못생긴 수’에 해당한다는 점이 포인트이다.
2의 배수 변수, 3의 배수 변수, 5의 배수 변수에 대하여 각각 ‘가장 작은 못생긴 수’부터 오름차순으로 하나씩 확인하면서, 각 배수를 곱한 값도 ‘못생긴 수’가 될 수 있도록 처리하면 정답 판정을 받을 수 있다.
예를 들어 먼저 못생긴 수로 1이 있다고 해보자. 이때 각각 2의 배수, 3의 배수, 5의 배수를 구하면 다음과 같다.
- 2의 배수: 1 x 2 = 2
- 3의 배수: 1 x 3 = 3
- 5의 배수: 1 x 5 = 5
이로써 우리는 새롭게 2, 3, 5 또한 못생긴 수에 해당한다는 것을 알 수 있다. 따라서 이를 고려했을 때, 전체 못생긴 수는 {1, 2, 3, 5}가 된다.
첫 번째로 못생긴 수인 1에 이어서 그다음으로 못생긴 수는 2가 된다. 이때 각각 2의 배수, 3의 배수, 5의 배수를 구하면 다음과 같다.
- 2의 배수: 2 x 2 = 4
- 3의 배수: 2 x 3 = 6
- 5의 배수: 2 x 5 = 10
이로써 우리는 4, 6, 10이 못생긴 수에 해당한다는 것을 알 수 있다. 따라서 이를 고려했을 때, 전체 못생긴 수는 {1, 2, 3, 4, 6, 10}이 된다. 이렇게 못생긴 수들을 작은 수부터 차례대로 확인하면서, 각 못생긴 수에 대해서 2의 배수, 3의 배수 , 5의 배수를 고려한다는 점을 기억하여 효율적으로 소스코드를 작성하면 다음과 같이 작성할 수 있다.
💻 코드
import java.util.*;
public class Main {
static int n;
static int[] ugly = new int[1000]; // 못생긴 수를 담기 위한 테이블 (1차원 DP 테이블)
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
// 2배, 3배, 5배를 위한 인덱스
int i2 = 0, i3 = 0, i5 = 0;
// 처음에 곱셈 값을 초기화
int next2 = 2, next3 = 3, next5 = 5;
ugly[0] = 1; // 첫 번째 못생긴 수는 1
// 1부터 n까지의 못생긴 수들을 찾기
for (int l = 1; l < n; l++) {
// 가능한 곱셈 결과 중에서 가장 작은 수를 선택
ugly[l] = Math.min(next2, Math.min(next3, next5));
// 인덱스에 따라서 곱셈 결과를 증가
if (ugly[l] == next2) {
i2 += 1;
next2 = ugly[i2] * 2;
}
if (ugly[l] == next3) {
i3 += 1;
next3 = ugly[i3] * 3;
}
if (ugly[l] == next5) {
i5 += 1;
next5 = ugly[i5] * 5;
}
}
// n번째 못생긴 수를 출력
System.out.println(ugly[n - 1]);
}
}
[출처 : 이것이 코딩 테스트다 with 파이썬 - 나동빈 저]
'알고리즘 > 이코테' 카테고리의 다른 글
[구현] 이코테 게임 개발(Java) (0) | 2022.11.22 |
---|---|
[그리디] 이코테 곱하기 혹은 더하기(Java) (0) | 2022.07.28 |
[그리디] 이코테 모험가 길드(Java) (0) | 2022.07.26 |