题目链接:
1.阶乘求和 - 蓝桥云课 (lanqiao.cn)
说明:
说难也不难,说简单也不简单,就是考你敏不敏锐。想到末尾位数为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;
}