快轉到主要內容

CSES-1618 Trailing Zeros

標籤: 數學
目錄

題目連結:https://cses.fi/problemset/task/1618


題意
#

題目給定一個整數 \( n \),要計算 \( n! \)(也就是 \( 1 \times 2 \times 3 \dots \times n \))這個乘出來極度巨大的數字,它的最尾端會連續出現幾個 0?

思路
#

要產生結尾的 0,數學上的本質其實就是看看這整串乘法裡面,總共可以配對出多少組「 \( 2 \times 5 \) 」。
想一下階乘的展開式,裡面偶數(包含 2 的倍數)可以說是滿地都是,數量絕對比 5 的倍數還要多出非常多。這代表我們擁有的 2 根本不缺,這場配對遊戲的瓶頸完全卡在「我們能湊出幾個 5」上面。

所以這題直接轉變成:去算這 \( 1 \) 到 \( n \) 個數字總共貢獻了多少個質因數 5?
我們可以先把 \( n \) 除以 5,就能算出有幾個數字貢獻了第一層的 5;接著再把算出來的數字繼續除以 5(相當於算 \( n \) 裡面有幾個 25 的倍數),把它們額外貢獻的第二層 5 也加進來。就這樣用個 while 迴圈一路除下去,把所有算出來的商數加起來,真正的答案就出來了。

程式碼
#

#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define fi first
#define se second
#define INF LONG_LONG_MAX/1000
#define WA() cin.tie(0)->sync_with_stdio(0)
#define all(x) (x).begin(), (x).end()
#define int long long
#define PII pair<int, int>

signed main() { WA();
    int n, cnt = 0; // cnt 用來累加 5 的質因數數量
    cin >> n; // 讀取欲計算階乘的數字 n
    
    // 不斷將 n 除以 5,藉此算出每一層有幾個 5 的倍數貢獻出質因數 5
    while (n >= 5) {
        n /= 5;
        cnt += n; // 把這層算出來的 5 的數量加總起來
    }
    cout << cnt; // 輸出配對出 10 的總組數,也就是結尾 0 的數量
}
Piau 的筆記本
作者
Piau 的筆記本
希望我寫下來的東西能夠長久的記在我的腦中