由于题目中给出的数据范围较大,即使用 long long 也会造成数据溢出,所以要用到高精度的运算.
学习了高精度运算之后就知道,可以用数组来储存范围大的整数,于是,这道题我就是将数据从1开始依次相乘,每乘一次就将结果保存尽数组当中,然后与前一次乘积结果相加以达到高精度求和的目的.
以下是我写的代码.
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 100;
int a[MAXN], b[MAXN], c[MAXN];//a 储存本次乘积结果, b 储存上次乘积结果,c 储存 a和b之和;
int len = 1; // 数据长度;
void sum()
{
for (int i = 0; i <= len; i++)
{
c[i] += a[i] + b[i]; //对每一位进行求和;
c[i + 1] += c[i] / 10;// 模拟加法进位;
c[i] %= 10;
}
if (c[len])//最后进位可能会导致位数增加;
len++;
}
void mp(int y)
{
memset(b, 0, sizeof(b));//初始化数组 b;
for (int i = 0; i < len; i++)
{
a[i] *= y; // 让 a 数组中每一位数都乘上 y,完成高精度数和整型数的乘积;
}
for (int i = 0; i < len; i++) // 模拟乘积后的进位.
{
a[i+1] += a[i] / 10;
a[i] %= 10;
}
int x = a[len];
while (x) // 重置长度 len,使数组每一位都是个位数;
{
a[len] = x % 10;
x /= 10;
len++;
}
sum();
for (int i = 0; i <= len; i++)
{
b[i] = a[i];
}
}
int main ()
{
int n;
a[0] = 1;
cin >> n;
for (int i = 1; i <= n; i++)
{
mp(i);
}
for (;!c[len];)//重置长度,保留有效长度;
len--;
for (int i = len; i >= 0; i--)
cout << c[i];
return 0;
}