#include <algorithm>
#include<bits/stdc++.h>
using namespace std;
const long long mod=10000000000;
long long jiechen(int n)
{
    long long k=1;
    if(n==0) return 1;
    for(int i=1;i<=n;i++)
    {
        k*=i;
        while(k%10==0)//去掉末尾零
        {
            k/=10;
        }
        k=k%mod;//保留最后几位
    }
    return k;
}

int main()
{
    int n;
    cin>>n;
    long long s=jiechen(n);
    cout<<s%10<<'\n';
   return 0;
}

这一题就是从右往左数找出n的阶乘的第一位不等于零的数。

难点就在于,要处理数据会爆的问题,阶乘的数据很大,long long也要爆,我们找的是第一个不为零的数字可以只看部分的数据,所以我们可以对中间过程的k取模

为什么可以取模?

题目只关心从右往左第一个非零数字,也就是个位数(在去掉末尾所有 0 之后)。

数学原理:

  • 乘法的结果,个位数只取决于参与乘法的每个数的个位数以及进位
  • 如果我们在计算过程中只保留最后几位数字,不会影响最终个位数的正确性
  • 保留 10 位足够安全,因为乘法中低位的进位最多影响几位
  • 去掉一个末尾0,相当于除以10,也就是去掉一对因子(2,5)

    去掉这对(2,5)会影响最右边的非零数字吗?

    方法一:正常计算

    text

    1×2=2
    2×3=6
    6×4=24
    24×5=120    ← 末尾有1个0
    120×6=720
    720×7=5040
    5040×8=40320
    40320×9=362880
    362880×10=3628800
    

    末尾有2个0,去掉后得 36288,个位数是 8

    方法二:边乘边去0

    text

    1×2=2
    2×3=6
    6×4=24
    24×5=120 → 去0 → 12    ← 提前去掉0
    12×6=72
    72×7=504 → 去0?504末尾不是0,不动
    504×8=4032
    4032×9=36288
    36288×10=362880 → 去0 → 36288
    

    最后 36288,个位数是 8。结果一样!