题目链接:
说明:
说难也不难,说简单也不简单,就是考你敏不敏锐。想到末尾位数为0加起来就不影响了,以及阶乘里产生一个10就多一个0就很容易了。
还有蓝桥杯常考的:为了防溢出,不断取余的思想。这里我考虑到了累加取余,但是没考虑到求阶乘的时候也要取余,不然的话阶乘就太大了,会溢出。
为什么求阶乘的时候也能取余而不影响结果呢,因为我们只关注末尾九位数的情况,做乘法的时候,而影响结果末尾9位的就是两个乘数的末尾九位(看注释,想象一下手算乘法的方式)。
还有一个地方就是求阶乘的时候不要重复从1开始求,求i的阶乘直接利用i-1的阶乘结果*i。这些细节都需要注意,把得到的信息利用起来。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e9;//注意:9个0就是10位数了
int ans=0;
//1到40刚好能组合出9个0,2*5,10,15*一个偶数,20,25*4两个0,30,35*一个偶数,40
//只需要计算到39!就可以,后面的阶乘都有9个0,对末尾9个数无影响
signed main() {
cin.tie(0);
cout.tie(0);
int sum=0;
int m=1;
for(int i=1;i<=39;i++){
m=m*i;
//对于乘法来说,影响结果末尾9个数的肯定只有 该被乘数的末9位,想象一下手算乘法的方式
// XX123456789 被乘数
//* 11 ,以11为例,一个两位的乘数(因为在本题中只到两位)
//————————
// XX123456789
//XX123456789
//————————
// 结果末尾9位只被乘数和两位数的乘数的末9位影响
//所以每一次对某数的阶乘 取9位数 的余
m=m%1000000000ll;
sum=(sum+m)%1000000000ll;
}
cout<<sum%1000000000ll;
return 0;
}