https://www.acmicpc.net/problem/1676
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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int n;
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
int total = 1;
int cnt = 0;
while (n >= 5) {
cnt += n / 5;
n /= 5;
}
System.out.println(cnt);
}
}
|
cs |
문제의 핵심은 뒤에서부터 처음 0이 아닌 수가 나올때 까지 0의 개수이다.
그렇다면 0이 되려면 2와 5가 필요하다는 것(2*5=10)을 생각해볼 수 있다.
그런데 어차피 팩토리얼이므로 5가 나온 뒤 2가 나올거고, 당연히 2가 5의 개수보다 많을거기에 5의 개수가 0의 개수랑 같다고 생각해 볼 수 있다.
그러면 소인수분해를 통해 이 문제를 해결해볼 수 있는데,
예를 들어 5!이면 120이다. 이것을 소인수 분해하면 2^3*3*5가 된다 여기서 5의 개수는 1이고, 0의 개수도 1이다.
10! 의 경우 0의 개수가 2인데 10! 안에는 5가 2번 들어가 있다.
20!의 경우 0의 개수가 4인데 여기 안에도 5,10,15,20으로 5가 4번 들어가 있다.
그렇다면 n에서 5를 나누면 되지 않을까? 하는 생각이 든다. 하지만 지금까지는 5*1, 5*2, 5*3, 5*4 등 5가 1제곱만 포함되지만,
50!의 경우 25나 50이 포함되면서 5의 2제곱이 포함된다. 이런경우 5의 개수를 유실할 수 있다.
그러므로 n을 5로 나눠줌으로 써, 여러번 5가 곱해진 경우도 포함시켜준다.
더이상 n이 5로 나눠질 수 없을 때 까지 반복문을 돌려준다. (n이 5보다 크거나 같을 때까지만) -->while문 사용
while(n>=5){
cnt+=n/5; // 5가 1제곱만 포함된 경우
n/=5; // 5가 n 제곱 ( 단, n>1) 포함된 경우를 찾기 위해 5로 한번더 나눠준다.
추가
10을 만들려면 2와 5가 필요하다. 그렇기에 2와 5를 각각 나눈것을 고려해볼것이다. 즉,2의 승수와 5의 승수 중 더 작은 값을 가져오는 알고리즘을 구현해볼 것이다.
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
|
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static int n;
public static int count2(int n) {
int cnt = 0;
while (n >= 2) {
cnt += n / 2;
n /= 2;
}
return cnt;
}
public static int count5(int n) {
int cnt = 0;
while (n >= 5) {
cnt += n / 5;
n /= 5;
}
return cnt;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
System.out.println(Math.min(count2(n), count5(n)));
}
}
|
cs |
'Java > 백준' 카테고리의 다른 글
[java 백준] 실버 5/ 14912번 숫자 빈도수 (0) | 2021.07.26 |
---|---|
[java 백준] 실버 5/ 16208번 귀찮음 (0) | 2021.07.20 |
[java 백준] 브론즈 2/ 1592번 영식이와 친구들 (0) | 2021.07.19 |
[java 백준] 실버 5/ 1934번 최소 공배수 (0) | 2021.07.18 |
[java 백준] 브론즈 3/ 1267번 핸드폰 요금 (1) | 2021.07.18 |
댓글