#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。结果一样!



京公网安备 11010502036488号