티스토리 뷰

문제

 

3474번: 교수가 된 현우

첫째 줄에 테스트 케이스의 개수 T가 주어지고, 이어서 T개의 줄에 정수 N이 주어진다(1 <= N <= 1000000000).

www.acmicpc.net

알고리즘의 킹갓제너럴엠퍼러마제스티충무공알고리즘마스터 현우가 교수로 취임하였다!

그러나 학생들에게 크나큰 기대를 품고 첫 수업에 들어갔던 현우는 아무도 외판원 순회 문제(Traveling Salesman Problem, TSP)를 풀지 못하는 것을 보고 낙심하였다.

그 와중에 학생 남규는 TSP를 완전탐색으로 풀려고 하였고, 현우는 그걸 보고 경악을 금치 못한다. 왜냐면 TSP를 완전탐색으로 풀려면 O(N!)의 시간이 소모되는데, 이는 경악을 금치 못할 시간이기 때문이다.

그러나 남규는 O(N!)이 왜 큰지도 잘 모른다. 그래서 현우는 더더욱 경악을 금치 못하고, N!이 얼마나 큰지 대략적으로나마 알려주기 위해, 자연수 N이 주어지면 N!의 오른쪽 끝에 있는 0의 개수를 알려주기로 하였다.

그러나 현우는 경악을 금치 못하여 지금 코딩을 할 수 없는 상황이다. 여러분이 현우를 대신하여 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어지고, 이어서 T개의 줄에 정수 N이 주어진다(1 <= N <= 1000000000).

출력

각 줄마다 N!의 오른쪽 끝에 있는 0의 개수를 출력한다.


문제 이해하기

 N!의 오른쪽 끝에 있는 0의 개수를 구하려면 N!의 소인수 중 5의 개수를 구하면 됩니다. 0의 개수를 구하려면 10의 x승으로 N!이 나누어 떨어지는 x의 최댓값을 구해야 합니다. 즉, N!의 소인수를 사용해 10을 몇 개 만들 수 있는지를 구하는 문제입니다. 여기서 10을 구하기위해 2와 5가 필요한데 N!의 소인수 2의 개수는 항상 5의 개수보다 많습니다. 따라서 소인수 5의 개수를 구하면 자연스럽게 x의 최댓값을 구할 수 있습니다.


코드

use std::io::{stdin, stdout, BufWriter, Write};

fn main() {
    let mut writer = BufWriter::new(stdout());
    let mut lines = stdin().lines();

    let n = line_to_number(&lines.next().unwrap().unwrap());

    // x!의 0의 개수는 x를 소인수분해 했을 때 5의 개수와 같다. (2의 개수는 항상 5의 개수보다 많으므로)
    for i in 0..n {
        let x = line_to_number(&lines.next().unwrap().unwrap());

        let mut y = 5;
        let mut cnt = 0;

        while y <= x {
            cnt += x / y;
            y *= 5;
        }

        writeln!(writer, "{}", cnt).unwrap();
    }
}

fn line_to_number(s: &str) -> i32 {
    s.parse().unwrap()
}

메모리: 13212 KB
시간: 20 ms
분류: 수학, 정수론

글에서 수정이 필요한 부분이나 설명이 부족한 부분이 있다면 댓글로 남겨주세요!
최근에 올라온 글
최근에 달린 댓글
«   2024/11   »
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
Total
Today
Yesterday
글 보관함