📖 APS/BOJ
[APS][C++] BOJ S5 1676번 팩토리얼 0의 개수 (feat. 0의 개수의 비밀)
청월누리
2025. 2. 9. 20:58
https://www.acmicpc.net/problem/1676
문제
$ N! $ 에서 뒤에서부터 처음 0이 아닌 숫자가 나올 때까지 0의 개수를 구하는 프로그램을 작성하시오.
입력
- 첫째 줄에 N이 주어진다. (0 ≤ N ≤ 500)
출력
- 첫째 줄에 구한 0의 개수를 출력한다.
풀이
$ N! $ 에서 0의 개수는 5의 지수(소인수로서 5가 총 몇번 곱해졌는지)를 확인하면 된다.
- 연속된 0의 개수는 팩토리얼의 소인수 분해에서 10이 몇 번 곱해졌는지에 따라 변화함
- 10은 2와 5가 각각 하나씩 모일 때마다 만들어지기 떄문에 소인수로서 5가 총 몇 개가 있느냐에 따라 결정됨 (2는 모든 짝수의 소인수이기 때문에 소인수로서 2는 5보다 무조건 많을 수 밖에 없음)
- 아래 수식을 코드로 구현하면 해결이 가능함
$$ \left\lfloor \frac{n}{5} \right\rfloor + \left\lfloor \frac{n}{5^2} \right\rfloor + \left\lfloor \frac{n}{5^3} \right\rfloor + \cdots $$
코드
#include <cmath>
#include <iostream>
using namespace std;
int main() {
int N;
cin >> N;
int cnt = 0;
for (int i = 1; i < 4; i++) {
cnt += N / int(pow(5, i));
}
cout << cnt;
return 0;
}
결과
오답 원인
- 처음에는 위 규칙이 아니라 팩토리얼을 모두 계산한 후 0을 세는 방식으로 작성했더니 C++에서 표현할 수 있는 수의 범위를 넘어갔기 떄문에 오답이 출력됨 (오버플로우로 인한 오류)
- 따라서 오버플로우를 방지하기 위해 다른 방법이 필요하였으며, 위 코드를 통해 해결