P1009 [NOIP1998 普及组] 阶乘之和
原创
©著作权归作者所有:来自51CTO博客作者小游坦之的原创作品,请联系作者获取转载授权,否则将追究法律责任
写一篇简单的题解,蒟蒻感觉高精度未来可能会用到,故聊以记之,以求不忘而已。
![P1009 [NOIP1998 普及组] 阶乘之和_算法](https://s2.51cto.com/images/blog/202209/26114047_63311f3f3419035202.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=/resize,m_fixed,w_1184)
这是一道求阶乘的题目,我们首先想到的方法就是递归求值。但是肯定会超出范围,即使用long long,最多也不过19位,而50的阶乘和足足求65位,所以我们用高精度的模板来做。
首先定义一个a数组,用来存i的阶乘;
【高精度求i的阶乘】
void aa(int n)
{
int jw=0;
for(int i=1;i<500;i++)
{
a[i] =a[i]*n+jw;
jw=a[i]/10;
a[i]%=10;
}
}
三点注意:
1、如何求出来的阶乘,我们在主函数中调用n次,每一次调用前的a数组里面存放的是i-1的阶乘,在乘以i,就是i的阶乘
2、为什么要遍历500次,因为不知道a存放的这个数的位数是多少,这个500也是一个浮动值,只要保证大于最大数的位数即可
3、jw是i-1的进位,对10取余是保留下个位数
s用来存阶乘和
void ss(int n)
{
int jw=0;
for(int i=1;i<500;i++)
{
s[i]+=a[i]+jw;
jw=s[i]/10;
s[i]%=10;
}
}
差不多同a一样,只不过他是把a加起来
主代码
#include <iostream>
using namespace std;
int s[500];
int a[500];
void aa(int n)
{
int jw=0;
for(int i=1;i<500;i++)
{
a[i] =a[i]*n+jw;
jw=a[i]/10;
a[i]%=10;
}
}
void ss(int n)
{
int jw=0;
for(int i=1;i<500;i++)
{
s[i]+=a[i]+jw;
jw=s[i]/10;
s[i]%=10;
}
}
int main()
{
int n;
cin>>n;
a[1]=1;
for(int i=1;i<=n;i++)
{
aa(i);
ss(i);
}
int flag=0;
for(int i=499;i>=1;i--)
{
if(s[i]){
flag=1;
}
if(flag)
{
cout<<s[i];
}
}
}
提醒:
1、注意数组不要越界
2、不要用if(s[i])cout<<s[i];因为有效数中也可能有0
估计是多余的,大家都比我聪明;
快快乐乐刷题,安安静静进步,共勉之。