题目描述
用高精度计算出S=1!+2!+3!+…+n! (n≤50)
其中“!”表示阶乘,例如:5!=5×4×3×2×1。
输入格式
一个正整数N。
输出格式
一个正整数S,表示计算结果。
粗糙原始版:
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 10010;
string tra(int a)//用来将int转化为string类型
{
string b, c;
while (a > 0)
{
b += a % 10 + '0';
a /= 10;
}
for (int i = b.length() - 1; i >= 0; i--)
{
c += b[i];
}
return c;
}
string add(string a, string b)//大数相加
{
int na[N] = { 0 }, nb[N] = { 0 };
string ans;
int la = a.size(), lb = b.size();
//倒序存储字符串
for (int i = 0; i < la; i++)
{
na[i] = a[la - 1 - i] - '0';
}
for (int i = 0; i < lb; i++)
{
nb[i] = b[lb - 1 - i] -'0';
}
int len = la > lb ? la : lb;
//核心代码
for (int i = 0; i < len; i++)
{
na[i] += nb[i];
na[i + 1] += na[i] / 10;
na[i] %= 10;
}
//消去最高位0
if (!na[len])
{
len--;
}
for (int i = len; i >= 0; i--)
{
ans += na[i] + '0';
}
return ans;
}
string mul(string a1,string b1)//大数相乘
{
int a[N] = { 0 }, b[N] = { 0 }, c[N] = { 0 };
string ans;
int la = a1.size(), lb = b1.size();
//倒序存储
for (int i = 1; i <= la; i++)
{
a[i] = a1[la - i] - '0';
}
for (int i = 1; i <= lb; i++)
{
b[i] = b1[lb - i] - '0';
}
for (int i = 1; i <= la; i++)
{
for (int j = 1; j <= lb; j++)
{
//注意这里乘法是错位相加!
c[i + j - 1] += a[i] * b[j];
}
}
for (int i = 1; i <= la + lb; i++)
{
if (c[i] > 9)//大于9的需要进位
{
c[i + 1] += c[i] / 10;
c[i] %= 10;
}
}
//最后相乘答案的位数必然不超过两个数位数之和
int len = la + lb;
//去掉高位多余的0
while (len > 1 && c[len] == 0)
{
len--;
}
for (int i = len; i >= 1; i--)
{
ans +=c[i]+'0';
}
return ans;
}
int main()
{
int n;
cin >> n;
string sum = "0";//保存最后的结果
for (int i = 1; i <= n; i++)
{
string ans = "1";//保存i的阶乘
for (int j = 1; j <= i; j++)
{
ans = mul(ans, tra(j));
}
sum = add(sum, ans);
}
cout << sum;
return 0;
}
优化版:
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
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;
}
vector<int> mul(vector<int>& a, vector<int> &b)//高精 * 高精
{
vector<int> c(a.size() + b.size());
for(int i = 0; i < a.size(); i++)
{
for(int j = 0; j < b.size(); j++)
{
c[i + j] += a[i] * b[j];
}
}
for(int i = 0, t = 0; i < c.size() || t; i++)
{
t += c[i];
c[i] = t % 10;
t /=10;
}
while(c.size() > 1 && !c.back()) c.pop_back();
return c;
}
int main()
{
int n;
cin >> n;
vector<int> res;
res.push_back(0);
for (int i = 1; i <= n; i++)
{
//tmp记录每个i的阶乘
vector<int> tmp;
tmp.push_back(1);
for (int j = 1; j <= i; j++)
{
vector<int> a;
int k = j;
while (k)
{
a.push_back(k % 10);
k /= 10;
}
tmp = mul(tmp, a);
}
res = add(tmp, res);
}
for (int i = res.size() - 1; i >= 0; i--)
{
cout << res[i];
}
return 0;
}
另:
vector<int> mul(vector<int>& a, int b)//高精 * 低精
{
vector<int> c;
int t = 0;
for (int i = 0; i < a.size() || t; i++)
{
t += a[i] * b;
c.push_back(t % 10);
t /= 10;
}
while (c.size() > 1 && !c.back()) c.pop_back();
return c;
}