Processing math: 100%
728x90
728x90

문제

(nm)의 끝자리 0의 개수를 출력하는 프로그램을 작성하시오.

 

입력

첫째 줄에 정수 nm (0mn2,000,000,000 n0)이 들어온다.

 

 

출력

첫째 줄에 (nm)의 끝자리 0의 개수를 출력한다.

 

예제 입력 1

25 12

 

예제 출력 1 

2
 

 

알고리즘 분류

  • 수학
  • 정수론

 

문제 출처

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

 

2004번: 조합 0의 개수

첫째 줄에 정수 nm (0mn2,000,000,000, n0)이 들어온다.

www.acmicpc.net

 


 

문제 해결 방법

  • '팩토리얼 0의 개수' 문제와 비슷한 유형의 문제이다.
  • 팩토리얼에서 0의 개수는 5의 지수 개수만 구하면 문제를 해결할 수 있었지만, 조합의 경우 다음과 같이 나누기 연산이 이루어지므로 10을 만드는 약수인 2와 5의 지수 개수를 모두 구해줘야 한다.
nCr=n!r!(nr)!
  • 위의 공식에서 n!r!, 그리고 (n-r)!2와 5의 지수 개수를 모두 구해준 후, n! 의 2와 5의 지수 개수에서 r!(n-r)! 의 2와 5의 지수 개수의 합을 각각 빼주면 된다. 
// nCm = n! / m! x (n - m)!
numTwo = findNumOfDivisors(2, n) - (findNumOfDivisors(2, m) + findNumOfDivisors(2, n - m)); // 2의 지수의 개수 계산
numFive = findNumOfDivisors(5, n) - (findNumOfDivisors(5, m) + findNumOfDivisors(5, n - m)); // 5의 지수의 개수 계산
  • 그리고 최종적으로 구해진 2의 지수 개수(numTwo)와 5의 지수 개수(numFive) 중, 작은 수를 출력시켜준다.
// 조합은 나누기 연산을 해야하고, 2 * 5 = 10 이기 때문에 둘 중에 작은 것을 출력시킨다.
result = (numTwo > numFive) ? numFive : numTwo;

 

  • 팩토리얼에서 지수의 개수를 구하는 알고리즘은 다음과 같다.
방법 1
ull findNumOfDivisors(int div, ull n) {
int count = 0;
while (n >= div) {
count += n / div;
n /= div;
}
return count;
}

 

방법 2
ull findNumOfDivisors(int div, ull n) {
int count = 0;
for (ull i = div; i <= n; i *= div) {
count += (n / i);
}
return count;
}

 

코드

#include <iostream>
using namespace std;
using ull = unsigned long long;
ull n, m, numTwo, numFive, result;
// div의 지수의 개수 찾기
ull findNumOfDivisors(int div, ull n) {
int count = 0;
while (n >= div) {
count += n / div;
n /= div;
}
return count;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
cin >> n >> m;
// nCm = n! / m! x (n - m)!
numTwo = findNumOfDivisors(2, n) - (findNumOfDivisors(2, m) + findNumOfDivisors(2, n - m)); // 2의 지수 개수 계산
numFive = findNumOfDivisors(5, n) - (findNumOfDivisors(5, m) + findNumOfDivisors(5, n - m)); // 5의 지수 개수 계산
// 조합은 나누기 연산을 해야하고, 2 * 5 = 10 이기 때문에 둘 중에 작은 것을 출력시킨다.
result = (numTwo > numFive) ? numFive : numTwo;
cout << result << '\n';
return 0;
}

 

채점 결과

 

참고

  • [단계별로 풀어보기] > [정수론과 조합론]
  • 실버II

팩토리얼(Factorial)에서 지수의 개수를 구하는 알고리즘

10!=10×9×8×7×6×5×4×3×2×1=28×34×52×71

2의 지수는 8, 3의 지수는 4, 5의 지수는 2, 7의 지수는 1이다.
  • 팩토리얼에서 지수의 개수를 구하는 알고리즘은 다음과 같다.
방법 1
int findNumOfDivisors1(int div, int n) {
int count = 0;
while (n >= div) {
count += n / div;
n /= div;
}
return count;
}

 

방법 2
int findNumOfDivisors2(int div, int n) {
int count = 0;
for (ull i = div; i <= n; i *= div) {
count += (n / i);
}
return count;
}
728x90
728x90

'Problem Solving > BOJ' 카테고리의 다른 글

[BOJ-15652][C++] N과 M (4)  (0) 2022.11.18
[BOJ-15651][C++] N과 M (3)  (0) 2022.11.18
[BOJ-15650][C++] N과 M (2)  (0) 2022.11.18
[BOJ-15649][C++] N과 M (1)  (0) 2022.11.17
[BOJ-1676][C++] 팩토리얼 0의 개수  (0) 2022.11.15
[BOJ-9375][C++] 패션왕 신해빈  (0) 2022.11.15
[BOJ-1010][C++] 다리 놓기  (0) 2022.11.15
[BOJ-11051][C++] 이항 계수 2  (0) 2022.11.15

문제입력출력예제 입력 1예제 출력 1 알고리즘 분류문제 출처문제 해결 방법코드채점 결과참고팩토리얼(Factorial)에서 지수의 개수를 구하는 알고리즘