思路
1.我们需要求出k!(k=1..2...3......n)
由于20!就会爆掉,因此,本题可以使用高精度,我们可以先预处理前面9个,并把前面9个的和加起来,从第十个开始采用高精度
void pro()
{
sum[0]=0;
a[0] = 1;
for(int i = 1;i<=9;i++)
{
a[i]=a[i-1]*i;
sum[i]+=a[i]+sum[i-1];
}
}
2、我们需要求出9之后的每个元素的阶乘
根据n! = (n-1)! * n,以下就是高精度大数×小数的模板
vector<int> muti(vector<int> &A,int b)
{
int t = 0;
vector<int> C;
for(int i = 0;i<A.size()||t;i++)
{
if(i<A.size()) t += A[i]*b;
C.push_back(t%10);
t/=10;
}
while(C.size()>1&&C.back()==0) C.pop_back();
return C;
}
3、求出来之后,肯定是要加起来的,10!+(前面9个的高精度)
其实就是一个高精度加法的模板
vector<int> add(vector<int> &A,vector<int> &B)
{
vector<int> C;
int t = 0;
for(int i = 0;i<A.size()||i<B.size();i++)
{
if(i<A.size())t+=A[i];
if(i<B.size())t+=B[i];
C.push_back(t%10);
t/=10;
}
if(t) C.push_back(t);
return C;
}
4、完整代码如下:
#include<iostream>
#include<vector>
using namespace std;
#include<cmath>
const int N = 55;
int a[N],sum[N];
int n;
void pro()
{
sum[0]=0;
a[0] = 1;
for(int i = 1;i<=9;i++)
{
a[i]=a[i-1]*i;
sum[i]+=a[i]+sum[i-1];
}
}
vector<int> muti(vector<int> &A,int b)
{
int t = 0;
vector<int> C;
for(int i = 0;i<A.size()||t;i++)
{
if(i<A.size()) t += A[i]*b;
C.push_back(t%10);
t/=10;
}
while(C.size()>1&&C.back()==0) C.pop_back();
return C;
}
vector<int> add(vector<int> &A,vector<int> &B)
{
vector<int> C;
int t = 0;
for(int i = 0;i<A.size()||i<B.size();i++)
{
if(i<A.size())t+=A[i];
if(i<B.size())t+=B[i];
C.push_back(t%10);
t/=10;
}
if(t) C.push_back(t);
return C;
}
int main()
{
cin>>n;
vector<int> v1,v2;
pro();
int t = a[9],t1=sum[9];
if(n<=9)
printf("%d",sum[n]);
//其中v1是一个加起来的,v2是累加和,先对单独的处理,再与之前的相加
else
{
while(t>0)
{
v1.push_back(t%10);
t = t /10;
}
while(t1>0)
{
v2.push_back(t1%10);
t1/=10;
}
for(int i = 10;i<=n;i++)
{
v1 = muti(v1,i);// v1每次会是新的,v2也是
v2 = add(v1,v2);
}
for(int i = v2.size()-1;i>=0;i--)
{
cout<<v2[i];
}
}
return 0;
}
5、简化代码(直接从开始就运用高精度思想)
#include<iostream>
#include<vector>
using namespace std;
const int N = 55;
// 高精度乘法
vector<int> multiply(vector<int> &a, int b) {
vector<int> c;
int carry = 0;
for (int i = 0; i < a.size() || carry; i++) {
if (i < a.size()) {
carry += a[i] * b;
}
c.push_back(carry % 10);
carry /= 10;
}
while (c.size() > 1 && c.back() == 0) c.pop_back();
return c;
}
// 高精度加法
vector<int> add(vector<int> &a, vector<int> &b) {
if (a.size() < b.size()) return add(b, a);
vector<int> c;
int carry = 0;
for (int i = 0; i < a.size(); i++) {
carry += a[i];
if (i < b.size()) carry += b[i];
c.push_back(carry % 10);
carry /= 10;
}
if (carry) c.push_back(carry);
return c;
}
int main() {
int n;
cin >> n;
vector<int> factorial = {1}, sum = {0};
for (int i = 1; i <= n; i++) {
factorial = multiply(factorial, i);
sum = add(sum, factorial);
}
for (int i = sum.size() - 1; i >= 0; i--) cout << sum[i];
cout << endl;
return 0;
}