[백준] 2312번 - 수 복원하기 [Java][C++]
[백준] 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(MAX));
int T = Integer.parseInt(br.readLine());
for (int tc = 1; tc <= T; tc++) {
int N = Integer.parseInt(br.readLine());
for (int prime : primes) {
if (prime * prime > N) break; // prime의 제곱보다 작으면 탐색 종료
int cnt = 0;
while (N % prime == 0) {
N /= prime;
cnt++;
}
if (cnt > 0) sb.append(prime).append(" ").append(cnt).append("\n");
}
if (N > 1) sb.append(N).append(" 1\n"); // N이 처음부터 소수인 경우와 합성수를 소인수분해한 후 소수가 남은 경우
}
System.out.println(sb);
}
static boolean[] sieve(int N) {
boolean[] isPrime = new boolean[1 + N];
Arrays.fill(isPrime, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= N; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= N; 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
57
58
59
60
61
62
#include <bits/stdc++.h>
using namespace std;
constexpr int MAX = 100000;
vector<bool> sieve(int n) {
vector<bool> isPrime(1 + n, true);
isPrime[0] = isPrime[1] = false;
for (int i = 2; i * i <= n; i++) {
if (isPrime[i]) {
for (int j = i * i; j <= n; j += i) {
isPrime[j] = false;
}
}
}
return isPrime;
}
vector<int> prime_list(const vector<bool>& isPrime) {
vector<int> v;
for (int i = 2; i < isPrime.size(); i++) {
if (isPrime[i]) v.push_back(i);
}
return v;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
vector<int> primes = prime_list(sieve(MAX));
int t;
cin >> t;
for (int tc = 1; tc <= t; tc++) {
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이 처음부터 소수인 경우와 합성수를 소인수분해한 후 소수가 남은 경우
}
}
}
3. 풀이 정보
1. 소인수분해 [Java]
| 언어 | 시간 | 메모리 | 코드 길이 |
|---|---|---|---|
| Java 11 | 120 ms | 14640 KB | 1725 B |
2. 소인수분해 [C++]
| 언어 | 시간 | 메모리 | 코드 길이 |
|---|---|---|---|
| C++ 17 | 0 ms | 2156 KB | 1305 B |
This post is licensed under CC BY 4.0 by the author.