본문 바로가기
알고리즘/기초수학

[java 백준] 실버 2/2004번 조합 0의 개수

by Meaning_ 2021. 9. 18.
728x90
반응형

https://www.acmicpc.net/problem/2004

 

2004번: 조합 0의 개수

첫째 줄에 정수 $n$, $m$ ($0 \le m \le n \le 2,000,000,000$, $n \ne 0$)이 들어온다.

www.acmicpc.net

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
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
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());
 
        long n = Long.parseLong(st.nextToken());
        long m = Long.parseLong(st.nextToken());
        long nm = n - m;
        long Count5 = count5(n) - count5(nm) - count5(m);
        long Count2 = count2(n) - count2(nm) - count2(m);
        System.out.println(Math.min(Count5, Count2));
 
    }
 
    public static long count5(long n) {
        long count5 = 0;
        while (n >= 5) {
            count5 += n / 5;
            n /= 5;
        }
        return count5;
 
    }
 
    public static long count2(long n) {
        long count2 = 0;
        while (n >= 2) {
            count2 += n / 2;
            n /= 2;
        }
        return count2;
 
    }
 
}
cs

 

이 문제를 풀면서 고려해줘야하는 사항이 두가지 있는데

 

1. 조합이므로 예를 들어 10c2 이면 10!/8!*2! 이다 즉 나누는 수가 필요하게 되는데 어차피 우리가 구하는건 5의 n승,2의 n승이기에 지수끼리 계산할때 나눗셈은 뺄셈이 된다! 

 

2. 앞에 말한 것 처럼 10을 만들땐 2와 5가 필요하다. 그렇기에 조합에서 5의 승수와 2의 승수중 더 작은게 조합 0의 개수가 된다. Math.min 사용하면 된다.

 

문제를 풀면서 했던 틀린 생각


이 문제를 풀기전 0의 개수니까 이번 문제도 당연히 5를 나누면 되겠지~ 했는데 2까지 고려해줘야했다.

 

1676번 팩토리얼의 개수와 매우 비슷하다!

https://we1cometomeanings.tistory.com/54

 

[java 백준] 실버 4/ 1676번 팩토리얼 0의 개수

https://www.acmicpc.net/problem/1676 1676번: 팩토리얼 0의 개수 N!에서 뒤에서부터 처음 0이 아닌 숫자가 나올 때까지 0의 개수를 구하는 프로그램을 작성하시오. www.acmicpc.net 1 2 3 4 5 6 7 8 9 10 11 12..

we1cometomeanings.tistory.com

 

1676번은 5로만 나눠줬는데 왜 이 문제는 2까지 나누는걸 고려해야할까?

 

우선 저 문제의 경우 나누는게 없다. 즉, 10! 이면 딱 10부터 1까지 곱해주는거지 별 다른 연산이 없다는 것이다. 원래 0을 만들려면 5와2가 필요한데 어차피 2보다 5가 크니까(5가 곱해지면 어차피 앞에 2가 곱해지니까) 2를 딱히 신경쓰지 않은것이다. 저 문제도 2의 승수, 5의 승수 중 더 작은것을 print하는 방법으로 풀 수 있고 첨부해 놓았다.

 

예를 들어 10C2일때 

 

5의 승수만 고려하면 

 

10!/2!*8! --> 2-(0+1)=1

 

2의 승수만 고려하면

 

10!/2!*8! --> 5+2+1-(1+4+2+1) =0

 

즉 둘 중 작은 건 2의 승수를 고려한 0이다.

 

이러한 반례가 있기에 둘 중 더 작은 것을 고르는 방법을 사용해야하는 것이다. 

 

 

 

 

참고한 사이트


 

2의 승수와 5의 승수 중 더 작은것을 찾는 아이디어는 아래 링크에 첨부해둔 블로그를 참고했다!

https://st-lab.tistory.com/166

 

[백준] 2004번 : 조합 0의 개수 - JAVA [자바]

www.acmicpc.net/problem/2004 2004번: 조합 0의 개수 첫째 줄에 정수 n, m (0 ≤ m ≤ n ≤ 2,000,000,000, n ≠ 0)이 들어온다. www.acmicpc.net 문제 이전의 팩토리얼 0의 개수를 정확히 이해하고 풀었다면 쉽..

st-lab.tistory.com

 

728x90
반응형

댓글