石油大 HD阶乘 求阶乘末尾0的个数

博客围绕计算n的阶乘(n!)和双阶乘(n!!)末尾0的个数展开。因阶乘增长快,直接模拟复杂度高,通过分析可知判断末尾0个数可转化为求阶乘过程中因子5的个数,双阶乘本质相同。输入为正整数n(n ≤ 107),输出为n!和n!!末尾0的个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

n的阶乘定义为n! = n ∗ (n − 1) ∗ (n − 2) ∗ … ∗ 1。
n的双阶乘定义为n!! = n ∗ (n − 2) ∗ (n − 4) ∗ … ∗ 2或n!! = n∗ (n − 2) ∗ (n − 4) ∗ … ∗ 1,取决于n的奇偶性。
但是阶乘的增长速度太快了,所以我们现在只想知道n!和n!!末尾的0的个数。

输入

一个正整数n, n ≤ 107

输出

两个整数, 分别为n!和n!!末尾0的个数。

想法

阶乘太大了, 直接模拟复杂度太高, 百度一下发现有个规律, 记录一下
要判断末尾有几个0, 就是看这个数能整除几次10. 而能整除10,说明有因子5和2
阶乘过程中, 出现5的倍数之前一定会出现2的倍数(说明有了一个10), 反之,则不然
所以题目转化成了求阶乘过程中, 有几个因子5
双阶乘只是换了种形式, 本质不变

实现

#include <cstdio>
#include <iostream>
using namespace std;
int n, cnt1, cnt2;
void solve1(int n)
{
    while(n >= 1)
    {
        cnt1 += n/5;
        n /= 5;
    }
}
void solve2(int n)
{
    if(n&1) return;
    cnt2 += n/10;
    n /= 10;
    while(n >= 2)
    {
        cnt2 += n/5;
        n /= 5;
    }
}
int main()
{
    cin >> n;
    solve1(n);
    solve2(n);
    cout << cnt1 << " " << cnt2 << endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值