공부/백준\BeakJoon
[BEAKJOON] 백준 2004번 : 조합 0의 개수
na0-0
2023. 7. 16. 17:45
반응형
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
문제
접근
이전 팩토리얼 문제를 풀어봤으면, 한 팩토리얼 값의 5의 승수가 겹치는 수를 구해야한다.
문제는 nCr의 값을 구하는 것이기 때문에, 이항 계수의 공식을 생각하면 된다. 이항 계수의 공식은 팩토리얼 값으로 이루어져 있어서 이를 이용하면 쉽게 풀 수 있을 것이다.
조합은 영어로 combination이며, 고교 수학 내에서는 대문자 C를 사용하여 표현한다.
조합의 뜻은, nCr 의 뜻은 'n개 중에서 순서에 상관없이 r개를 뽑는 경우의 수' 이다.
일단 이항 계수를 구하는 공식은 다음과 같다.
이렇게 식으로 나타낼 수 있다.
풀이방법, 문제 봉착
사실 앞서 팩토리얼 문제는 당연히 2는 넘쳐 남으니까, 5에 대해서만 다루어줬는데, 5만 다루어주니까,
해당 문제에서는 "틀렸습니다"가 나온다.
https://www.acmicpc.net/board/view/323
글 읽기 - 채점 데이터에 취약점?같은게 있는것같습니다
댓글을 작성하려면 로그인해야 합니다.
www.acmicpc.net
문제에서 예시로준 25C12는 맞지만, 20C16은 올바른 값이 나오지 않는다.
그러면 2의 대한 것도 체크하고, 그 중에서 작은 수를 출력해주면 된다.
정답 코드
n, r = map(int, (input().strip()).split())
count_n_f = n
count_n_t = n
count_f = 0
while (count_n_f // 5 != 0):
count_f += 1
count_n_f //= 5
result_sum_f = 0
for i in range(1, count_f + 1):
result_sum_f += n // (5 ** i)
for i in range(1, count_f + 1):
result_sum_f -= r // (5 ** i)
for i in range(1, count_f + 1):
result_sum_f -= (n - r) // (5 ** i)
count_t = 0
while (count_n_t // 2 != 0):
count_t += 1
count_n_t //= 2
result_sum = 0
for i in range(1, count_t + 1):
result_sum += n // (2 ** i)
for i in range(1, count_t + 1):
result_sum -= r // (2 ** i)
for i in range(1, count_t + 1):
result_sum -= (n - r) // (2 ** i)
print(min(result_sum, result_sum_f))
반응형