[BaekJoon] 2312번 - 수 복원하기 [Java][C++]
[BaekJoon] 2312번 - 수 복원하기 [Java][C++]
1. 문제 풀이
주어진 수들을 소인수분해한 결과를 출력하는 문제로 에라토스테네스의 체를 활용해 소수들을 얻고 이 소수들로 $1$ 이 될 때까지 반복적으로 나누면 된다.
2. 코드
1. 풀이 [Java]
소수를 리스트로 얻은 후 각 소수들로 나눌 수 있으면 나누고 몫을 카운팅하는 방식으로 구현했다. 에라토스테네스의 체의 아이디어처럼 해당 소수의 제곱이 주어진 수보다 크면 더 탐색할 필요가 없으므로 종료하고 주어진 수를 소인수분해한 후 남은 수가 $1$ 보다 크면 해당 소수까지 넣어줬다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import java.io.*;
import java.util.*;
public class Main {
static final int MAX = 100_000;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
List<Integer> primes = getPrimes(sieve());
int t = Integer.parseInt(br.readLine());
while (t-- > 0) {
int n = Integer.parseInt(br.readLine());
for (int p : primes) {
if (p * p > n) break; // prime의 제곱보다 작으면 탐색 종료
int cnt = 0;
while (n % p == 0) {
n /= p;
cnt++;
}
if (cnt > 0) sb.append(p).append(" ").append(cnt).append("\n");
}
if (n > 1) sb.append(n).append(" 1\n"); // N이 처음부터 소수인 경우와 합성수를 소인수분해한 후 소수가 남은 경우
}
System.out.println(sb);
}
static boolean[] sieve() {
boolean[] isPrime = new boolean[1 + MAX];
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= MAX; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= MAX; j += i) {
isPrime[j] = false;
}
}
}
return isPrime;
}
static List<Integer> getPrimes(boolean[] isPrime) {
List<Integer> primes = new ArrayList<>();
for (int i = 2; i < isPrime.length; i++) {
if (isPrime[i]) primes.add(i);
}
return primes;
}
}
2. 풀이 [C++]
소수를 백터로 얻은 후 각 소수들로 나눌 수 있으면 나누고 몫을 카운팅하는 방식으로 구현했다. 에라토스테네스의 체의 아이디어처럼 해당 소수의 제곱이 주어진 수보다 크면 더 탐색할 필요가 없으므로 종료하고 주어진 수를 소인수분해한 후 남은 수가 $1$ 보다 크면 해당 소수까지 넣어줬다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <bits/stdc++.h>
using namespace std;
const int MAX = 100000;
bool isPrime[1 + MAX];
vector<int> primes;
void sieve() {
fill(isPrime, isPrime + MAX + 1, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= MAX; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= MAX; j += i) {
isPrime[j] = false;
}
}
}
for (int i = 2; i <= MAX; i++) {
if (isPrime[i]) primes.push_back(i);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
sieve();
int t;
cin >> t;
while (t--) {
int n;
cin >> n;
for (int p : primes) {
if (p * p > n) break; // p의 제곱보다 작으면 탐색 종료
int cnt = 0;
while (n % p == 0) {
n /= p;
cnt++;
}
if (cnt > 0) {
cout << p << ' ' << cnt << '\n';
}
}
if (n > 1) {
cout << n << ' ' << 1 << '\n'; // n이 처음부터 소수인 경우와 합성수를 소인수분해한 후 소수가 남은 경우
}
}
}
This post is licensed under CC BY 4.0 by the author.