前言
今天我们来做洛谷上的一道题目。
网址:[NOIP1998 普及组] 阶乘之和 - 洛谷
西江月·夜行黄沙道中 【宋】 辛弃疾
明月别枝惊鹊,清风半夜鸣蝉。稻花香里说丰年,听取WA声一片。
七八个星天外,两三点雨山前。旧时茅店社林边,路转溪桥忽见。
注:WA表示Wrong Answer
Bi------------------------------------
正文
这题一看过去这不So Easy吗?求一个数的阶乘还不简单?于是便有了以下代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
long long ans=1;
cin>>n;
for(int i=n;i>=1;i--) ans*=i;
cout<<ans<<endl;
return 0;
}
于是便有了:
真的是:稻花香里说丰年,听取WA声一片。
请你仔细读一读题目,题目让求的是阶乘之和,不是阶乘!
读懂了题,那还是So Easy,于是便有了以下代码:
#include<bits/stdc++.h>
using namespace std;
long long f(int x)
{
long long tmp=1;
for(int j=x;j>=1;j--) tmp*=j;
return tmp;
}
int main()
{
int n;
long long ans=0;
cin>>n;
for(int i=n;i>=1;i--) ans+=f(i);
cout<<ans<<endl;
return 0;
}
结果……:
真的是:稻花香里说丰年,听取WA声一片。
再请你仔细读一读题目,数据范围是n<=50,你不溢出谁溢出?
于是便有了高精度的代码:
#include<bits/stdc++.h>
using namespace std;
int cal=100,bignuma[110]{0,1},bignumb[110]{0,1};
long long f(int x)
{
long long tmp=1;
for(int j=x;j>=1;j--) tmp*=j;
return tmp;
}
void opea()
{
for (int j=1;j<=100;j++)
{
if (bignuma[j]>9)
{
bignuma[j+1]+=bignuma[j]/10;
bignuma[j]%=10;//取个位
}
}
}
void opeb()
{
for (int j=1;j<=100;j++)
{
bignumb[j]+=bignuma[j];
if (bignumb[j]>9)
{
bignumb[j+1]+=bignumb[j]/10;
bignumb[j]=bignumb[j]%10;
}
}
}
int main()
{
int n;
long long ans=0;
cin>>n;
if(n<=15)
{
for(int i=n;i>=1;i--) ans+=f(i);
cout<<ans<<endl;
}
else
{
for(int i=2;i<=n;i++)
{
for(int j=1;j<=100;j++) bignuma[j]*=i;
opea(); opeb();
}
for (cal=100;bignuma[cal]==0&&cal>0;cal--);
while (cal>0)
{
cout<<bignumb[cal];
cal--;
}
}
return 0;
}
结果:
终于是:稻花香里说丰年,听取AC声一片。
结尾
这一题纯纯是看你细不细心,如果不细心的话,就会像我一样,连着被坑两次。
文章不易,喜欢的话就点个赞再走吧。