#2014 소수의 곱
난이도 : 골드 1
유형 : 소수 / 우선순위 큐
▸ 문제
K개의 소수가 있다. 이때, 이 소수들 중에서 몇 개를 곱해서 얻게 되는 수들이 있을 것이다. 소수들을 선택할 때에는 같은 수를 선택해도 되며, 주어지는 소수 자체도 포함시키자.
예를 들어 세 소수가 2, 5, 7이었다면, 이러한 곱들을 오름차순으로 나타내 보면, 2, 4, 5, 7, 8, 10, 14, 16, 20, 25, 28, 32, 35, 등이 된다.
K개의 소수가 주어졌을 때, 이러한 소수의 곱들 중에서 N번째 수를 구해 보자. 단 정답은 231보다 작은 자연수이다.
▸ 입력
첫째 줄에 K(1 ≤ K ≤ 100), N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 K개의 소수가 오름차순으로 주어진다. 같은 소수가 여러 번 주어지는 경우는 없으며, 주어지는 소수는 모두 541보다 작거나 같은 자연수이다.
▸ 출력
첫째 줄에 문제에서 설명한 대로 소수의 곱을 나열했을 때, N번째 오는 것을 출력한다.
문제 풀이
수열에 있는 수들끼리의 곱을 구하는 문제이다. 그래서 n번째 수가 나올 때까지 곱해주면 되는데 기본적으로 O(n*k) 이중포문 시간복잡도에 추가로 정렬하는데 걸리는 시간 O(logN), 중복 탐지하는 시간 O(n)이 걸리기 때문에 O(n^2)이 훨씬 초과하여 시간복잡도가 발생한다.
O(n*k)는 필수이고, 정렬 또한 우선순위 큐에 진행해주므로 필수이다. 그래서 중복 탐지하는 부분을 감소시켜줘야 한다. 이는 소수의 곱셈부분의 중복을 제거해주면 된다.
- 소수의 곱 prime * prime은 중복이 이중포문에서는 두번씩 연산이 이루어지기 때문에 소수가 자신이 포함된 합성수를 만나면 연산을 종료해준다.
- 소수들 끼리는 당연히 중복이 발생하므로 자신의 소수값을 만날 때 까지만 곱을 해준다.
2 | 3 | 5 | 7 | |
2 | 2x2 | |||
3 | 3x2 | 3x3 | ||
5 | 5x2 | 5x3 | 5x5 | |
7 | 7x2 | 7x3 | 7x5 | 7x7 |
합성수의 경우도 마찬가지이다. (p x ... x q)로 이루어져있는 합성수도 자신을 포함한 소수를 만나면 뒤에 곱은 해주지 않아도 된다. 어차피 뒤에서 다른 소수가 자신의 턴이 올때 같은 연산을 해주기 때문이다.
- 예로 2x2x3 → 3x2x2 은 같은 연산인데 순서만 다를 뿐이다. 그래서 2가 추가되는 2x2x3연산은 패스하고 나중에 3이 추가되는3x2x2를 진행하게 해준다는 소리이다.
2 | 3 | 5 | 7 | |
4 | 2x2x2 | |||
6 | 2x3x2 | |||
8 | 2x2x2x2 | |||
9 | 3x3x2 | 3x3x3 |
풀이 코드
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int k = Integer.parseInt(st.nextToken());
int n = Integer.parseInt(st.nextToken());
long[] prime = new long[k];
Queue<Long> q = new PriorityQueue<>();
st = new StringTokenizer(br.readLine());
for(int i=0; i<k; i++) {
prime[i] = Integer.parseInt(st.nextToken());
q.add(prime[i]);
}
for(int i=0; i<n-1; i++) {
long num = q.poll();
for(int j=0; j<k; j++) {
long mul = num * prime[j];
q.add(mul);
if(num%prime[j] ==0)break;
}
}
System.out.println(q.poll());
}
}
'Dot Algo∙ DS > PS' 카테고리의 다른 글
[BOJ] 백준 2023번 신기한 소수 (Java) (0) | 2022.02.09 |
---|---|
[BOJ] 백준 1016번 제곱 ㄴㄴ수 (Java) (0) | 2022.02.08 |
[BOJ] 백준 2842번 집배원 한상덕 (Java) (0) | 2022.02.06 |
[BOJ] 백준 3745번 오름세 (Java) (0) | 2022.02.05 |
[BOJ] 백준 8983번 사냥꾼 (Java) (0) | 2022.02.04 |