PS

BOJ 9693 : 시파르

lickelon 2024. 12. 17. 23:41
  • 문제 링크 : boj.kr/9693
  • 난이도 : S4
  • 태그 : 정수론

코드

#include <bits/stdc++.h>

#define all(x) (x).begin(), (x).end()

#define INF 0x7FFFFFFF

using namespace std;

using ll = long long;
using ld = long double;
using pii = pair<int,int>;
using pll = pair<ll, ll>;

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);

    int T = 1;
    while(true) {
        int n;
        cin >> n;
        if(n == 0) break;
        int ans = 0;
        while(n) {
            ans += n / 5;
            n /= 5;
        }
        cout << "Case #" << T++ << ": " << ans << "\n";
    }
    return 0;
}

풀이

N!가 10으로 몇 번이나 나누어지는지 찾는 문제이다.

10은 2*5이고, 따라서 N!가 10으로 나누어지는 횟수는 N!의 약수가 몇 개의 2와 몇 개의 5로 이루어져 있는지 확인하면 된다.

N!안에는 2의 약수보다 5의 약수가 더 적을 수 밖에 없으므로 5의 약수의 개수를 세면 된다.

1~N까지 직접 5로 나눠보며 약수를 세어도 되지만, 더 쉽게 세는 방법이 있다.

5, 10, 15, 20, 25, ... 은 약수로 5를 갖는다. 따라서 5개의 정수마다 약수에 5가 하나씩 추가된다.

25, 50, 75, 100, ... 은 약수로 5^2를 갖는다. 따라서 5^2개의 정수마다 약수에 5가 하나씩 추가된다.

동일하게 5^K개의 정수마다 약수에 5가 하나씩 추가된다.

최종적으로 5의 약수의 개수는 N/5 + N/5^2 + N/5^3 + ... 이다.

728x90